December 2008 Entries
Frictionless IOC in ASP.NET MVC with Windsor/Binsor

For the past four months my controllers have had two constructors: one that received my dependencies and one parameterless that called Windsor directly, because parameterless constructors are a requirement for the default MVC ControllerFactory.  (These constructors did have a huge //HACK comment on them.)

Wiring up IOC with zero friction was quite simple.

First, we need to make a new ControllerFactory.  In it, we will ask Windsor to give us the controller.

public class CastleWindsorControllerFactory : DefaultControllerFactory { public override IController CreateController(RequestContext context, string controllerName) { return Container.Resolve<IController>(controllerName); } }

 

Then we just need to set this as the default ControllerFactory in our global.asax:

protected void Application_Start() { RegisterRoutes(RouteTable.Routes); ControllerBuilder.Current.SetControllerFactory(new CastleWindsorControllerFactory());

 

Then, if you like friction, you can stop here...  you'll just need to add a line to your Windsor config everytime you add a new Controller.  You will forget to do this and your code will break every time you add a new Controller.

If you want to never think about your controller's IOC again, we can use Binsor and programmatically register all of our controllers using reflection. 

For every type in our Web assembly, we'll see if a type is a controller. If it is a controller, we'll register it.

for type in Assembly.Load("Web").GetTypes(): if typeof(IController).IsAssignableFrom(type): Component(type.Name.Replace("Controller", String.Empty), IController, type, LifestyleType.Transient)

 

Don't forget to include LifestyleType.Transient.  By default, Windsor will return a singleton.  We do not want our controllers to be singletons.

And that's it.  You can just start creating controllers and never have to worry about wiring up their dependencies again.