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/