Unity and MVC (Constructor Injection, Property Injection)

May 8, 2008 at 12:37 PM
Is the Unity Framework only support Constructor Injection with MVC?

I have tried property (setter) injection. It seems not work and following error is occurred.

"System.StackOverflowException was unhandled."


May 8, 2008 at 12:53 PM
Can you post the code you used?
May 8, 2008 at 2:28 PM
It is very simple.

private UserService _userservice;

Dependency
private UserService UserService
{
get { return _userservice; }
set { _userservice = value; }
}

This won't work and return NULL. How could I solve it? It seems it don't get the object from unity.

BTW, "System.StackOverflowException was unhandled." is my problem. it is a typo.


private UserService _userservice;

public HomeController(UserService userservice)
{
_userservice = userservice;
}
May 8, 2008 at 3:08 PM
Try this code:

 
public class UserService
    {
        public string MyName;
    }
    public class HomeController
    {
        private UserService _userService;
        [Dependency]
        public UserService UserService
        {
            get { return _userService; }
            set { _userService = value; }
        }
        public HomeController(UserService userService)
        {
            _userService = userService;
        }
    }
 
[TestMethod]
        public void MyTest()
        {
            IUnityContainer container = new UnityContainer();
            container.RegisterType<UserService, UserService>();
            
            HomeController controller = container.Resolve<HomeController>();
 
            Assert.IsNotNull(controller);
 
 
            Assert.IsNotNull(controller.UserService);
 
        }
 

Cheers
Yaz
May 8, 2008 at 9:24 PM
How are you hooking into the MVC framework? What does your container.Resolve call look like, and where is it called.

I've used Unity with MVC lots of times, and all the injection methods worked for me. I suspect the issue is in the plumbing of how you've hooked up Unity and MVC.
May 9, 2008 at 4:58 AM

ctavares wrote:
How are you hooking into the MVC framework? What does your container.Resolve call look like, and where is it called.

I've used Unity with MVC lots of times, and all the injection methods worked for me. I suspect the issue is in the plumbing of how you've hooked up Unity and MVC.



I use the approach from David Hayden and code it under Application_Start as follows :-

protected void Application_Start(object sender, EventArgs e)
{
IUnityContainer container = new UnityContainer()
.RegisterType<IUserService, UserService>();


UnityControllerFactory factory = new UnityControllerFactory(container);

ControllerBuilder.Current.SetControllerFactory(factory);


RegisterRoutes(RouteTable.Routes);


}

It works for Constructor Injection but not Property(Setter) Injection.

May 9, 2008 at 6:05 AM
Which DependencyAttribute are you using: Microsoft.Practices.Unity.DependencyAttribute or Microsoft.Practices.Objectbuilder2.DependencyAttribute?

Please check your using statements in the definition of UserService and make sure you're using the one from Unity, not OB2.

The OB2 one will be removed in Unity 1.1 for precisely this reason.
May 9, 2008 at 6:21 AM


ctavares wrote:
Which DependencyAttribute are you using: Microsoft.Practices.Unity.DependencyAttribute or Microsoft.Practices.Objectbuilder2.DependencyAttribute?

Please check your using statements in the definition of UserService and make sure you're using the one from Unity, not OB2.

The OB2 one will be removed in Unity 1.1 for precisely this reason.



It uses Microsoft.Practices.Unity.DependencyAttribute but still not work.
May 10, 2008 at 5:34 AM
Could please send me a small, complete example of your code that does not work that i can compile and test with?

Send it to ctavares at microsoft.com.  Thanks.

-Chris
May 12, 2008 at 6:12 AM
It turned out the problem was something I should have spotted - the injected property was private.

May 12, 2008 at 6:39 AM
Thanks, it works now.
Aug 27, 2008 at 3:25 PM
Edited Aug 27, 2008 at 10:58 PM
What's the point in having the [Dependency] attribute if you are getting the value from the Constructor injection. This example seems useless. I could have done this to get the same result:

public class UserService
    {
        public string MyName;
    }

public class HomeController
{
    UserService _userService;
    
    public UserService UserService
    {
        get { return _userService; }
    }

    public HomeController(UserService userService)
    {
        _userService = userService;
    }
}

What I would like to see is something like this:

public class MyModule : IModule
{
    IUnityContainer container;
    
    public MyModule(IUnityContainer _container)
    {
        container = _container;
    }
    
    public void Inialize()
    {
        container.RegisterInstance<UserService>(container.Resolve<UserService>());
        HomeController controller = container.Resolve<HomeController>();
    }
}

public class UserService
    {
        public string MyName;
    }

public class HomeController
{
    [Dependency]   
    public UserService UserService { get; set; }

    public HomeController()
    { }
}


but I do not know if this would work...
Aug 27, 2008 at 11:00 PM
Edited Aug 28, 2008 at 12:53 PM
I tried my suggestion and it does work but not completely the way I envisioned. The only change I would make is:

public void Initialize()
{
    // Registering an instance will cause the Dependency attribute to be ignored
    // Instead registration is executed for the type to allow property dependency injection
    container.RegisterType<UserService, UserService>);
    HomeController controller = container.Resolve<HomeController>();
}

More discussion on the reasoning behind this change can be found here:

http://www.codeplex.com/CompositeWPF/Thread/View.aspx?ThreadId=34370

Andres Olivares