This is a re-post from the older blog. I’m retiring that blog address and this is one of those posts that I refer to when setting up a new project.
Using an IoC is one of those things that can take a time or two to understand where it fits in and how it’s useful. Once you cross the energy barrier, it’s a color in your palette you can’t imagine missing.
Imagine having a QuestionController that takes an interface called DomainRepository. The job of any concrete implementation of the DomainRepository will be to fetch various domain entities from a backing store.
public class QuestionController : Controller
{
private DomainRepository _repository;
public QuestionController(
DomainRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
ViewData.Model = _repository.AllQuestions;
return View();
}
}
This is a perfect place to use an IoC container to provide build a concrete implementation and all of it's dependencies
The gotcha is that ASP.NET MVC, by default, requires its controllers to have default constructors. Luckily, ASP.NET MVC uses a ControllerBuilder to instantiate the controllers using a ControllerFactory. This is an extension point where we can provider our own factory, one that uses the IoC of choice to resolve the controller.
You'll need a class for the new controller factory. This is a minimal implementation that doesn't make use of the MVC 2 requestContext parameter
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(
RequestContext requestContext,
Type controllerType)
{
return
ObjectFactory
.GetInstance(controllerType) as IController;
}
}
In your bootstrapper, or in the Global.asax.cs, make the ControllerBuilder use the new controller factory
ControllerBuilder.Current
.SetControllerFactory(
new StructureMapControllerFactory());
Also, in the bootstrapper, or in the Global.asax, setup your container. This is using StructureMap's 2.6.1 syntax
ObjectFactory.Initialize(factory =>
{
factory
.For<DomainRepository>()
.Use<NoSqlDomainRepository>();
});
These are the minimal steps required to get the ASP.NET MVC web application ready for use with an IoC (e.g., StructureMap).