Unity, Windsor and Autofac are three popular IoC containers that I’ve used when developing ASP.NET MVC applications. I’ve found, the easiest to set up and get going, is Autofac. In my last post, I explained how to create a Settings API with Entity Framework. In this post, I will show you how to add Autofac to the project, so that we can inject the dependencies into controllers.
Why Autofac?
One reason:
// Application_Start()
var builder = new ContainerBuilder();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));
It’s by far the most easiest IoC container to set up and get going. As you can see from the code above, it takes four lines of code to get constructor injection working on controllers. With Windsor and Unity, I found myself creating lots of plumbing code (this may have changed now).
How to Set Up Autofac?
Its easy, there are three steps to perform and then you can almost forget about the IoC container for the remainder of your projects development.
- Add Autofac to your project.
- Configure Autofac with autowiring.
- Add interfaces to dependencies you want injected.
Add Autofac to your project
Create a new ASP.NET MVC5 project and then run the following command at the package manager console:
Install-Package Autofac.Mvc5
Configure Autofac with autowiring
First of all we need to create a new AutofacConfig
class and store it in the App_Start
folder. Here’s an example:
public interface IDependency { }
public interface IPerWebRequest { }
public static class AutofacConfig
{
public static void RegisterDependencies()
{
var builder = new ContainerBuilder();
// autowire
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.As<IDependency>()
.AsImplementedInterfaces()
.InstancePerDependency();
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.As<IPerWebRequest>()
.AsImplementedInterfaces()
.InstancePerRequest();
// make controllers use constructor injection
builder.RegisterControllers(Assembly.GetExecutingAssembly());
// change the MVC dependency resolver to use Autofac
DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));
}
}
What is autowiring? Autowiring, is where you don’t need to manually register your dependencies with the IoC container. The application starts, and then the IoC container searches the project for dependencies to register.
There’s multiple ways you could achieve autowiring, you could search a namespace for dependencies, you could search for dependencies that end with a certain name, or you could use a technique that I borrowed from the Orchard team, which uses interfaces.
The AutofacConfig
class above uses two different interfaces to wire dependencies up using different lifetime scopes. The IPerWebRequest
is used to register dependencies so that only a single instance is instantiated for the duration of the web request. The IDependency
interface is used to register dependencies so that each time they are requested a new instance gets created.
Now that the config class has been created, we need to add the following line of code to the Application_Start
method of the Global.asax
class:
protected void Application_Start()
{
AutofacConfig.RegisterDependencies();
}
Add interfaces to dependencies you want injected
Now all you need to do is add either IPerWebRequest
or IDependency
to any dependencies that you want to inject into your controllers or services. In my last post, I created a Settings API which uses Entity Framework Code First as an example of managing application settings.
The following example shows how I’ve modified the UnitOfWork
and Settings
classes to implement IPerWebRequest
. You can download this project from GitHib.
public class UnitOfWork : DbContext, IUnitOfWork, IPerWebRequest
{
}
public class Settings : ISettings, IPerWebRequest
{
}
Notice the UnitOfWork
inherits the DbContext
and implements both the IUnitOfWork
and IPerWebRequest
interfaces. This means the IoC container will find this dependency and register it with the InstancePerRequest lifetime.
Lets See it In Action
Once the dependencies have had the required interfaces added to them, we can inject them into our controllers. The following example shows how this is done.
private readonly ISettings _settings;
public HomeController(ISettings settings)
{
_settings = settings;
}
public ActionResult SaveIoC()
{
_settings.General.SiteName = "Talk Sharp IoC";
_settings.Seo.HomeMetaDescription = "Welcome to Talk Sharp with IoC";
_settings.Save();
string output = string.Format("SiteName: {0} HomeMetaDescription {1}",
_settings.General.SiteName,
_settings.Seo.HomeMetaDescription
);
return Content(output);
}
One thing you will notice that’s different to the previous post, is there is no longer an instantiated UnitOfWork
passed into the Settings
class. This is now handled by the IoC container, and so is the disposal of the DbContext
. This is one of the benefits of IoC, you are passing the responsibility of instantiating and disposing of dependencies to the container.
This post has shown the very basics of using IoC with ASP.NET MVC. There is much more that Autofac can do. You can find more information in the Autofac getting started guide.