The ASP.NET MVC Framework allows the developer to specify a custom IControllerFactory Class to serve up Controller Classes. This opportunity allows us to use various Dependency Injection ( DI ) and Inversion of Control ( IoC ) containers to provide dependency injection services with our controllers. Here are two examples that will show this functionality using Castle Windsor and Spring.Net.
Specifying a DefaultControllerFactory in Global.asax
There is a System.Web.Mvc.ControllerBuilder Class that you can use within the Application_Start Event of the Global.asax File to specify the default ControllerFactory for the web application.
In this case, I will specify my custom class, ControllerFactory, to be the default ControllerFactory for the ASP.NET Application:
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
ControllerBuilder.Current.SetDefaultControllerFactory(typeof(ControllerFactory));
// ...
}
}
The Custom ControllerFactory Class
The CustomController Factory Class will implement the IControllerFactory Interface and look as follows:
public class ControllerFactory : IControllerFactory
{
public IController CreateController(RequestContext context, Type controllerType)
{
return IoC.Resolve<IController>(controllerType.Name);
}
}
ControllerFactory passes the name of the Controller Class requested by the ASP.NET MVC Framework to a static wrapper class, called IoC, that requests the controller from the dependency injection tool of your choice, which could be Castle Windsor, Spring.NET, etc. Values for controllerType.Name would be "HomeController", "ProductsController", "CustomersController", or whatever you happened to name your controller classes.
Castle Windsor for Dependency Injection
If you prefer to use Castle Windsor for dependency injection, the IoC wrapper class around the WindsorContainer can be as simple as:
public static class IoC
{
static readonly WindsorContainer container
= new WindsorContainer(HttpContext.Current.Server.MapPath
("~/Windsor.config"));
public static T Resolve<T>(string name)
{
return (T)container.Resolve(name);
}
}
The WindsorContainer is populated with components from a Windsor.config file in the root of the ASP.NET application. An example of the Windsor.config class could look as follows:
<configuration>
<components>
<component
id="CustomersDataSource"
service="MvcApplication1.Models.ICustomersDataSource, MvcApplication1"
type="MvcApplication1.Models.CustomersDataSource, MvcApplication1"
lifestyle="singleton" />
<component
id="CustomersController"
type="MvcApplication1.Controllers.CustomersController, MvcApplication1"
lifestyle="transient" />
<component
id="HomeController"
type="MvcApplication1.Controllers.HomeController, MvcApplication1"
lifestyle="transient" />
</components>
</configuration>
SpringFramework.Net for Dependency Injection
If you prefer to use Spring.Net for dependency injection, the IoC wrapper class around the IObjectFactory can be as simple as:
public static class IoC
{
static readonly IObjectFactory factory
= new XmlObjectFactory(new FileSystemResource
(HttpContext.Current.Server.MapPath("~/Spring.config")));
public static T Resolve<T>(string name)
{
return (T)factory.GetObject(name);
}
}
The ObjectFactory is populated with components from a Spring.config file in the root of the ASP.NET application. An example of the Spring.config class could look as follows:
<objects xmlns="http://www.springframework.net">
<object
id="CustomersDataSource"
type="MvcApplication1.Models.CustomersDataSource, MvcApplication1" />
<object
id="HomeController"
type="MvcApplication1.Controllers.HomeController, MvcApplication1" />
<object
id="CustomersController"
type="MvcApplication1.Controllers.CustomersController, MvcApplication1">
<constructor-arg name="dataSource" ref="CustomersDataSource"/>
</object>
</objects>
Conclusion
The ASP.NET MVC Framework and the ability to create your own IControllerFactory to serve up Controller Classes using your Dependency Injection Tool of choice is an exciting feature.