ASP.NET MVC 2 Framework and Unity 2.0 Dependency Injection Container

Update! Download sample project MvcWithUnity.VS2010.zip

This is an update to a previous post on MVC and Unity: Dependency injection in ASP.NET MVC with Unity IoC Container

After my previous post, new versions of both ASP.NET MVC and Unity has been released and some confusion about their compatibility has shown up on the Internet. The first hit on Google on the topic is this which is completely wrong and uninformed. BillKrat writes:

"MVC2 will pull the rug out from under these blogs because the IControllerFactory interface for CreateController no longer provides a "type" - it provides a "string" which will simply hold the controllerName; not as easy to work with."

In fact, this is not the case at all. The following snippet is fresh out of the code repository from the MVC 1.0 relase:

   1: public interface IControllerFactory 
   2: { 
   3:     IController CreateController(RequestContext requestContext, 
   4:                                  string controllerName); 
   5:     void ReleaseController(IController controller); 
   6: }

thus, the interface has not changed at all, and all samples on integrating ASP.NET MVC with Unity still apply!

What BillKrat has done is to mistake the interface for the base implementation in System.Web.Mvc.DefaultControllerFactory. If we subclass DefaultControllerFactorty all we need to do is this (as I’ve explained previously):

   1: public class UnityControllerFactory : DefaultControllerFactory 
   2: { 
   3:     private readonly IUnityContainer container; 
   4:     public UnityControllerFactory(IUnityContainer container) 
   5:     { 
   6:         this.container = container; 
   7:     } 
   8:     protected override IController GetControllerInstance(
   9:                 RequestContext requestContext, Type controllerType) 
  10:     { 
  11:         return container.Resolve(controllerType) as IController; 
  12:     }
  13: }

thus, here we get our type which plays very nicely with Unity’s Resolve method.

Comments (5) -

  • 123

    2014-02-09 00:38:51 | Reply

    Using the above code exactly gives:

    'UnityControllerFactory.GetControllerInstance(System.Type)': no suitable method found to override

    The following compiles:

    public class UnityControllerFactory : DefaultControllerFactory
    {
    IUnityContainer container;

    public UnityControllerFactory(IUnityContainer container)
    {
    this.container = container;
    }

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
    return container.Resolve(controllerType) as IController;
    }

    }

    • Rickard

      2014-02-09 00:39:16 | Reply

      Thanks for pointing that out. The difference between MVC 1 and MVC 2 with regards to DefaultControllerFactory is the extra RequestContext parameter. Which we don't need for the Unity integration.
      I've updated the code sample.

  • Rickard

    2014-02-09 00:39:31 | Reply

    Sample project is now available for download at the top of the post

  • C. Shea

    2014-02-09 00:40:25 | Reply

    Also, UnityContainer.Resolve does not take just one argument as of Unity 2.0. It takes at least 2. The signature I think most would be interested in is UnityContainer.Resolve(Type t, string typeName). So in your example above, you should call the following line of code: return container.resolve(controllerType, controllerType.Name);

    • Rickard

      2014-02-09 00:40:50 | Reply

      @C. Shea: You are right in that UnityContainer.Resolve takes two arguments.

      However, the method I use in the code sample above is an Extension method from the Microsoft.Practices.Unity.UnityContainerExtensions class.

Loading
Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.