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
- public class CustomControllerActivator : IControllerActivator
- {
- IController IControllerActivator.Create(
- System.Web.Routing.RequestContext requestContext,
- Type controllerType)
- {
- return DependencyResolver.Current
- .GetService(controllerType) as IController;
- }
- }
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.
- public class UnityDependencyResolver : IDependencyResolver
- {
- IUnityContainer container;
- public UnityDependencyResolver(IUnityContainer container)
- {
- this.container = container;
- }
- public object GetService(Type serviceType)
- {
- try
- {
- return container.Resolve(serviceType);
- }
- catch
- {
- return null;
- }
- }
- public IEnumerable<object> GetServices(Type serviceType)
- {
- try
- {
- return container.ResolveAll(serviceType);
- }
- catch
- {
- return new List<object>();
- }
- }
- }
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
- protected void Application_Start()
- {
- AreaRegistration.RegisterAllAreas();
- RegisterGlobalFilters(GlobalFilters.Filters);
- RegisterRoutes(RouteTable.Routes);
- IUnityContainer container = GetUnityContainer();
- DependencyResolver.SetResolver(new UnityDependencyResolver(container));
- }
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
- private IUnityContainer GetUnityContainer()
- {
- //Create UnityContainer
- IUnityContainer container = new UnityContainer()
- .RegisterType<IControllerActivator, CustomControllerActivator>()
- .RegisterType<IFormsAuthenticationService, FormsAuthenticationService>()
- .RegisterType<IMembershipService, AccountMembershipService>()
- .RegisterInstance<MembershipProvider>(Membership.Provider)
- .RegisterType<IDatabaseFactory, DatabaseFactory>(new HttpContextLifetimeManager<IDatabaseFactory>())
- .RegisterType<IUnitOfWork, UnitOfWork>(new HttpContextLifetimeManager<IUnitOfWork>())
- .RegisterType<ICategoryRepository, CategoryRepository>(new HttpContextLifetimeManager<ICategoryRepository>())
- .RegisterType<IExpenseRepository, ExpenseRepository>(new HttpContextLifetimeManager<IExpenseRepository>())
- .RegisterType<ICategoryService, CategoryService>(new HttpContextLifetimeManager<ICategoryService>())
- .RegisterType<IExpenseService, ExpenseService>(new HttpContextLifetimeManager<IExpenseService>());
- return container;
- }
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/