Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

In my previous examples for dependency injection in ASP.NET MVC, I have used an approach where creating a custom controller factory deriving from DefaultControllerFactory and override the GetControllerInstance method for dependency injection. But ASP.NET MVC 3 is providing great support for dependency injection with very nice abstraction. In this post, I will demonstrate how to achieve dependency injection using two interfaces introduced in ASP.NET MVC 3 - IDependencyResolver and IControllerActivator. Unity 2.0 will be using as the dependency injection  container for this demo app.

Custom Controller Activator class using IControllerActivator

ASP.NET MVC 3 has introduced a new interface IControllerActivator which lets you activate controllers with custom behavior and can be use it for dependency  injection purpose.The IControllerActivator interface is discoverable using the dependency resolver. Let’s create a custom controller activator class by deriving from IControllerActivator intreface

  1. public class CustomControllerActivator : IControllerActivator
  2.     {        
  3.         IController IControllerActivator.Create(
  4.             System.Web.Routing.RequestContext requestContext,
  5.             Type controllerType)
  6.         {
  7.             return DependencyResolver.Current
  8.                 .GetService(controllerType) as IController;
  9.         }      
  10.     }

 Custom Dependency Resolver class using IDependencyResolver

ASP.NET MVC 3 has introduced a new interface IDependencyResolver which exposes two methods - GetService and GetServices.The GetService method resolves singly registered services that support arbitrary object creation and the GetServices resolves multiply registered services. Implementations of the IDependencyResolver interface should delegate to the underlying dependency injection container to provide the registered service for the requested type. When there are no registered services of the requested type, the ASP.NET MVC framework expects implementations of this interface to return null from GetService and to return an empty collection from GetServices. Let’s create a custom dependency resolver class by deriving from IDependencyResolver intreface in order to working with Unity to providing dependency injection.

 

  1. public class UnityDependencyResolver : IDependencyResolver
  2. {        
  3.     IUnityContainer container;       
  4.     public UnityDependencyResolver(IUnityContainer container)
  5.     {
  6.         this.container = container;
  7.     }
  8.  
  9.     public object GetService(Type serviceType)
  10.     {
  11.         try
  12.         {
  13.             return container.Resolve(serviceType);
  14.         }
  15.         catch
  16.         {               
  17.             return null;
  18.         }
  19.     }
  20.  
  21.     public IEnumerable<object> GetServices(Type serviceType)
  22.     {
  23.         try
  24.         {
  25.             return container.ResolveAll(serviceType);
  26.         }
  27.         catch
  28.         {                
  29.             return new List<object>();
  30.         }
  31.     }
  32. }

 Configure the Unity container with DependencyResolver.SetResolver Method

The below code in the Global.asax.cs configure the Unity container using SetResolver method of DependencyResolver class

  1. protected void Application_Start()
  2. {
  3.     AreaRegistration.RegisterAllAreas();
  4.     RegisterGlobalFilters(GlobalFilters.Filters);
  5.     RegisterRoutes(RouteTable.Routes);
  6.     IUnityContainer container = GetUnityContainer();
  7.     DependencyResolver.SetResolver(new UnityDependencyResolver(container));
  8. }

The SetResolver method of DependencyResolver class provides a registration point for dependency injection containers. In this method, we configure the UnityDependencyResolver class for providing dependency injection with Unity 2.0. The SetResolver method will be working with any dependency injection container.If you want to use StructureMap  as the dependency injection container, you can create a dependency resolver class in order to working with StructureMap  by deriving IDependencyResolver intreface and later you can configure this class with SetResolver method. The ASP.NET MVC 3 is providing an excellent support for working  with dependency injection containers.

The GetUnityContainer method is shown below

  1. private IUnityContainer GetUnityContainer()
  2.  {
  3.      //Create UnityContainer          
  4.      IUnityContainer container = new UnityContainer()
  5.      .RegisterType<IControllerActivator, CustomControllerActivator>()
  6.      .RegisterType<IFormsAuthenticationService, FormsAuthenticationService>()
  7.      .RegisterType<IMembershipService, AccountMembershipService>()
  8.      .RegisterInstance<MembershipProvider>(Membership.Provider)
  9.      .RegisterType<IDatabaseFactory, DatabaseFactory>(new HttpContextLifetimeManager<IDatabaseFactory>())
  10.      .RegisterType<IUnitOfWork, UnitOfWork>(new HttpContextLifetimeManager<IUnitOfWork>())
  11.      .RegisterType<ICategoryRepository, CategoryRepository>(new HttpContextLifetimeManager<ICategoryRepository>())
  12.      .RegisterType<IExpenseRepository, ExpenseRepository>(new HttpContextLifetimeManager<IExpenseRepository>())
  13.      .RegisterType<ICategoryService, CategoryService>(new HttpContextLifetimeManager<ICategoryService>())
  14.      .RegisterType<IExpenseService, ExpenseService>(new HttpContextLifetimeManager<IExpenseService>());
  15.      return container;         
  16.  }

 In the above GetUnityContainer method, I added the registration for IControllerActivator type into the Unity container along with other types. This will use concrete class CustomControllerActivator for the type IControllerActivator.

Source Code

You can download the source code from my demo app for ASP.NET MVC 3 and EF Code First at http://efmvc.codeplex.com/

Published Friday, January 21, 2011 7:38 AM by shiju

Comments

# re: Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

Monday, January 24, 2011 9:22 PM by Alex

Yea, I used the same approach with Unity, and I hate the fact that you need to resort to a try/catch to determine if Unity can resolve a given type. It seems like Ninject handles this specific case better with the TryGet which returns null.

# re: Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

Tuesday, January 25, 2011 2:28 AM by TT

@Alex: Unity 2.0 has IsRegistered method you can use to check existence before resolving, try...catch is no more the only option.

# re: Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

Tuesday, January 25, 2011 11:29 PM by Alex

@TT Yea, but that only tells you if a given type is registered in the container. What it doesn't tell you is if the types it depends on is in the container.

e.g. IF you're trying to resolve a controller like so:

public HomeController(IRepository repo){}

So in your DependencyResolver when trying to resolve the HomeController, Unity will tell you whether or now HomeController is Registered with with container, it won't however tell you whether or not it can actually resolve IRepository which is needed to successfully create a HomeContoller.

# re: Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

Wednesday, January 26, 2011 3:59 PM by Michiel

Your blog post series about ASP.Net MVC 3, EF and Unity is really great! The sample code on codeplex is also very helpful! Thanks a lot.

# re: Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

Wednesday, March 23, 2011 10:14 PM by cwlaualex

Do you think the following is a better implementation? All controllers are skipped from the IsRegistered checking.

if (typeof(IController).IsAssignableFrom(serviceType))

                   return _container.Resolve(serviceType);

               else

                   return _container.IsRegistered(serviceType) ? _container.Resolve(serviceType) : null;

# re: Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

Wednesday, May 11, 2011 9:31 AM by tensai ango-ango

Nice post dude. It helped me a lot.

What if we're making custom providers (e.g. session state store, membership, etc.) together with service/repository pattern, how can we configure the container to resolve dependency?

Thanks!

# re: Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

Wednesday, July 6, 2011 9:40 AM by gykosa

I added only an empty Unity container to my application and it is still working fine.

Is there a fall-back mechanism to the default resolver if the custom resolver cannot resolve a type?

# re: Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

Tuesday, August 16, 2011 9:44 AM by Murugesan

Is it possible to do dependency Injection without any third party plugins such as Spring.NET or StructureMap?

# re: Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

Friday, October 7, 2011 6:54 AM by nabog

I don't think you need to implement IControllerActivator. Just implement IDependencyResolver and take out the line ".RegisterType<IControllerActivator, CustomControllerActivator>()"

# re: Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

Sunday, December 11, 2011 5:12 PM by Nuri Yılmaz

Hi,

I would like to seperate UI > service > Data, but bootstrapper need known assembly type for register data repositories which needs by services.

suppose it;

CustomerService get ctor injection ICustomerRepository

ICustomerRepository need connection string but I dont want to know which connection string uses for CustomerService.

How should I define repositories?

Thanks

# re: Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

Tuesday, February 7, 2012 5:00 AM by Suril

Really great article for beginners.. Thanks a lot

# re: Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

Friday, April 20, 2012 7:30 AM by Muhammad

Really great article

# re: Dependency Injection in ASP.NET MVC 3 using DependencyResolver and ControllerActivator

Sunday, October 7, 2012 3:20 PM by TtRAKpaDsQeI

wvlkcw I think this is a real great post. Want more.

Leave a Comment

(required) 
(required) 
(optional)
(required)