ASP .NET MVC Controller Factory with Windsor

11.02.2010 20:19Comments
In this post I will show you how to create your custom Controller Factory for ASP .NET MVC using windsor and other things you can do with it. First if you don't know Windsor, it's an Inversion of Control Container which allows you to inject dependencies dinamically. I strongly recommend to read about it in castle project's website here.

Custom Controller Factory

In order to create your own custom controller factory, you can inherit the DefaultControllerFactory that ships with MVC. The real magic happens when you override the GetControllerInstance(Type controllerType) method in which you will return the instance of the specified controller. In order to create the instance with Windsor you first need to register the types in the container. (I took this sample from the book Pro ASP.NET MVC Framework, which is awesome by the way): public class WindsorControllerFactory : DefaultControllerFactory { WindsorContainer container; // The constructor: // 1. Sets up a new IoC container // 2. Registers all components specified in web.config // 3. Registers all controller types as components public WindsorControllerFactory() { // Instantiate a container, taking configuration from web.config container = new WindsorContainer( new XmlInterpreter(new ConfigResource("castle")) ); container.Kernel.AddFacility<
ServiceDependencyPropertiesFacility>(); // Also register all the controller types as transient var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes() where typeof(IController).IsAssignableFrom(t) select t; foreach (Type t in controllerTypes) { container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient); } } }
Basically it looks for all the classes in the Assembly which implement the IController interface, and then registers the type in the container. Once we have all the types registered we can go ahead and override the method like this:
// Constructs the controller instance needed to service each request protected override IController GetControllerInstance(Type controllerType) { return (IController)container.Resolve(controllerType); }
And last but not least! We need to register the controller in the Global.asax file:
protected void Application_Start() { RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory()); }
Now would we want to do this? Couple of reasons, first we can control the Lifestyle of the controllers re-utilizing controller's instances if we want to.  And second because it let's us take advantage of the Dependency Injection capabilities of Windsor. And even take advantage of the Interceptor and include AOP to our project! (more on this soon).

comments powered by Disqus