How to use Autofac for Dependency Injection in ASP.NET MVC application?

Recently, I published some posts that covers very important concepts like when to use Dependency Inversion Principle, Unit of Work, Repository design patterns in application. I recommend you to read these posts if you are new to these concepts. In this post, I’ll tell you how to use Autofac for Dependency Injection in ASP.NET MVC application. The same concept can also be applied to ASP.NET Web API application or any other .NET application as well.
Dependency Injection
The basic idea of the Dependency Injection is to have a separate object, an assembler, that populates a field in the lister class with an appropriate implementation for the finder interface.
– Martin Fowler
In other words, the idea behind inversion of control is that, rather than tie the classes in your application together and let classes “new up” their dependencies, you switch it around so dependencies are instead passed in during class construction.
I’ve been using same code in the posts linked above. In my last post to explain Dependency Inversion Principle, I refactored existing code to work with abstractions so that controllers doesn’t need to directly depend on any repository or entity framework detail. Just to recap, the code used in that post looks like following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public class EventsController : Controller { private readonly IUnitOfWork _unitOfWork; public EventsController() { _unitOfWork = new UnitOfWork(new ApplicationDbContext()); } public ActionResult Details(int id) { var event = _unitOfWork.Events.GetEvent(id); if (event == null) return HttpNotFound(); var viewModel = new EventDetailsViewModel { Event = event }; return View("Details", viewModel); } [Authorize] public ActionResult MyEvents() { var userId = User.Identity.GetUserId(); var events = _unitOfWork.Events.GetUpcomingEventsByArtist(userId); return View(events); } } |
The highlighted statement above creates an instance of UnitOfWork
and ApplicationDbContext
classes. So, this controller is directly dependent on these two classes.
Autofac Nuget Package
Let’s now add Autofac to move the responsibility of creating instances of classes from this controller to Autofac. I’m using ASP.NET MVC version 5, so I’ll be using Autofac’s MVC5 package for my application using Nuget package manager. Package Manager Console can also be used to install this via following command: install-package Autofac.MVC5
and make sure the correct MVC project is selected in the project dropdown option.
This package also installs another package named as Autofac
.
Builder
Autofac does not add any extra files to the project like other popular containers and it doesn’t automatically adds the dependency injection magic for classes directly. It is a little different to build the container using Autofac when compared to other IoC frameworks. Look at the code below to understand the process.
Instead few extra lines of code will be required to achieve this in Global.asax.cs
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
protected void Application_Start() { RegisterAutofac(); GlobalConfiguration.Configure(WebApiConfig.Register); AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } private void RegisterAutofac() { var builder = new ContainerBuilder(); builder.RegisterControllers(Assembly.GetExecutingAssembly()); builder.RegisterSource(new ViewRegistrationSource()); // manual registration of types; builder.RegisterType<LoggerService>.As<ILoggerService>(); builder.RegisterType<UnitOfWork>.As<IUnitOfWork>(); builder.RegisterType<ApplicationDbContext>(); // For property injection using Autofac // builder.RegisterType<QuoteService>().PropertiesAutowired(); var container = builder.Build(); DependencyResolver.SetResolver(container); } |
First, the ContainerBuilder
class is used to create a builder and all of the registration takes places within the context of this builder as shown on line no. 13 onwards above.
The RegisterControllers
method is then used to register all the types in the assembly that implements IController
interface. So, all the controllers will be registered properly. (Line no. 14)
In case you are also doing View Injection, then line no. 15 will be required in your application that basically registers a ViewRegistrationSource
to the builder.
Constructor & Property Injection
To inject instances of classes to constructor parameters, all other custom classes needs to be registered using RegisterType
method. The statement on line no. 18 shows how to register a LoggerService
and make its instance available to all the places wherever ILoggerService
interface is used. Note that concrete class is mentioned first and then the interface information is given to the builder unlike other IoC containers.
For property injection, use PropertiesAutoWired
method when registering a type and the property then doesn’t need to be decorated by any attribute like other IoC frameworks.
Container
Next, the builder definition is then used to build a container that can be given to the SetResolver
that basically provides a registration point for dependency resolvers using the provided common service locator when using a service locator interface.
Result
With the above changes, the controller code is now simplified even more as shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public class EventsController : Controller { private readonly IUnitOfWork _unitOfWork; public EventsController(IUnitOfWork unitOfWork) { _unitOfWork = unitOfWork; } public ActionResult Details(int id) { var event = _unitOfWork.Events.GetEvent(id); if (event == null) return HttpNotFound(); var viewModel = new EventDetailsViewModel { Event = event }; return View("Details", viewModel); } [Authorize] public ActionResult MyEvents() { var userId = User.Identity.GetUserId(); var events = _unitOfWork.Events.GetUpcomingEventsByArtist(userId); return View(events); } } |
As highlighted above, controller get an instance of UnitOfWork
class as this class implements IUnitOfWork
interface. Autofac is also smart enough to pass an instance of ApplicationDbContext
class to UnitOfWork
class constructor as it needs it at the time of construction based on following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class UnitOfWork : IUnitOfWork { private readonly ApplicationDbContext _context; public IEventRepository Events { get; private set; } public UnitOfWork(ApplicationDbContext context) { _context = context; Events = new EventRepository(context); } public void Complete() { _context.SaveChanges(); } } |
I hope this article explains you clearly how to use Autofac for Dependency Injection in ASP.NET MVC application. As I said in the beginning, the same concept can also be applied to ASP.NET Web API and other .NET applications. Please subscribe to my blog to read posts on similar topics.