Integrating Autofac with ASP.Net MVC 4. (25 min)
Tools required: (minimum)
- Autofac .NET IoC container
This post is aimed to demonstrate an implementation
of Autofac (IoC container) with ASP.NET MVC 4. As usual I will skip the theory
since you can just Google it (how would be the world without google) and find a
bunch of useful info about Dependency Injection
(book here), Inversion of control
and ASP.NET MVC 4.
1) Open Visual Studio and create a new
project, name it AutofacDemo
2) From Installed
Templates select Visual C# > ASP.NET
MVC4 Web Application > Click OK and then select template: Basic (An basic ASP.NET MVC 4 project)
3) Download Autofac binaries here (get release
for .NET 4).
4) Add the assemblies to the project.
5) Add a class to the project and name it AutofacScopeContainer
6) Replace the auto generated code for
your class with the following:
using System;
using System.Collections.Generic;
using HttpDependencies = System.Web.Http.Dependencies;
using Autofac;
using AutofacMvc = Autofac.Integration.Mvc;
namespace AutofacDemo
{
public class AutofacScopeContainer : HttpDependencies.IDependencyScope
{
protected AutofacMvc.AutofacDependencyResolver container;
public AutofacScopeContainer(AutofacMvc.AutofacDependencyResolver container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
if
(container.ApplicationContainer.IsRegistered(serviceType))
{
return this.container.GetService(serviceType);
}
else
{
return null;
}
}
public IEnumerable<object>
GetServices(Type serviceType)
{
if
(container.ApplicationContainer.IsRegistered(serviceType))
{
return this.container.GetServices(serviceType);
}
else
{
return new List<object>();
}
}
public void Dispose()
{
container.ApplicationContainer.Dispose();
}
}
public class AutoFacContainer : AutofacScopeContainer, HttpDependencies.IDependencyResolver
{
public AutoFacContainer(AutofacMvc.AutofacDependencyResolver container): base(container)
{
}
public HttpDependencies.IDependencyScope BeginScope()
{
return this;
}
}
}
7) Add another class and name it: Book and replace the auto generated code
for your class with the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace AutofacDemo
{
public class Book
{
public string ID { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public string Edition { get; set; }
public string ISBN10 { get; set; }
}
}
8) Add an Interface and name it: IBookRepository and replace the auto
generated code for your class with the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AutofacDemo
{
public interface IBookRepository
{
Book Get();
}
}
9) Add a class to implement IBookRepository
and name it: BookRepository and replace
the auto generated code for your class with the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace AutofacDemo
{
public class BookRepository : IBookRepository
{
public Book Get()
{
//
// Implement your web service or
your preferred ORM (EF/nhibernate/ mybatis.net...)
//
return new Book()
{
ID = "1",
Author = "Unknown",
Edition = "2012",
ISBN10 = "978-0061122415
",
Title = "Autofac
demo"
};
}
}
}
10)Add a controller and name it BookController
(Right click on Controllers
folder>Add>Controller>Template: Empty MVC controller)
11)Replace the auto generated code for BookController
with the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace AutofacDemo.Controllers
{
public class BookController : Controller
{
private readonly IBookRepository _bookRepository;
public BookController(IBookRepository bookRepository)
{
_bookRepository = bookRepository;
}
//
// GET: /Book/
public ActionResult Index()
{
//@model AutofacDemo.Book
var book = _bookRepository.Get();
// View Index.cshtml
return View(book);
}
}
}
12)Press Ctrl+Shift+B
(Build solution, we need it for the next step)
13)Right click on Index method and Select Add View > Select a strong-typed view > Model
class: Book (AutofacDemo)
>Scaffold template:Details>Click [Add] Button.
14)Open Global.asax (Global.asax.cs) and add the
following method to MvcApplication class
void SetUpAutoFac(HttpConfiguration config)
{
var builder = new ContainerBuilder();
builder.RegisterType<BookController>();
builder.RegisterType<BookRepository>().As<IBookRepository>();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
var resolver = new AutofacDependencyResolver(container);
config.DependencyResolver
= new AutoFacContainer(resolver);
}
15)Resolve assembly reference errors (Right click on
the errors, select resolve and the right assembly)
16) Add at the end of method Application_Start() the
following line of code
SetUpAutoFac(GlobalConfiguration.Configuration);
17)Open RouteConfig.cs located at App_Start and
change the value “Home” for “Book” as seen in the next screen shot
18)Press F5. From here you can start enjoying the benefits of
using Autofac container. Enjoy it!
Considerations
In the TDD world you would have first created a failing
test here, and there, then some code to pass the test, refactor, and refactor
again to finally have a decent code using your preferred coding best practices.
Well known testing frameworks: MSTest, NUnit, xUnit.