Configuring Castle Windsor in ASP.Net MVC

This tutorial shows you how to configure Castle Windsor for use with your ASP.Net MVC project. Note that his approach works in any version of MVC including ASP.Net MVC 3.0 even though it doesn’t use the new mechanisms offered to hook up IoC containers.

1) Installing Castle Windor

This is easy enough, just download it! However, if you want get slightly fancier I recommend you use NuGet since it’s getting quite popular. Whichever way you do it, we’ll be working with version 3.0 of Castle Windsor.

2)Create an IOC solution folder

This is purely for organizational purposes, but it’s good practice.

3)Create a custom ControllerFactory

We need to tap into ASP.Net MVC’s inner plumbings to tell it that we are going to provide the application with instances of all dependencies including controllers and anything that may be injected into our objects.

Create a class inside the IOC folder we created in step 2 and call it WindsorControllerFactory.cs. put the following code:

using System.Web;
using System.Web.Mvc;
using Castle.MicroKernel;

namespace Spike1.WebSite.IOC
{
    public class WindsorControllerFactory : DefaultControllerFactory
    {
        private readonly IKernel _kernel;

        public WindsorControllerFactory(IKernel kernel)
        {
            _kernel = kernel;
        }

        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, System.Type controllerType)
        {
            if (controllerType == null)
            {
                throw new HttpException(404, string.Format("The controller for path {0} cannot be found.", requestContext.HttpContext.Request.Path));
            }

            return (IController) _kernel.Resolve(controllerType);
        }

        public override void ReleaseController(IController controller)
        {
            _kernel.ReleaseComponent(controller);
            base.ReleaseController(controller);
        }
    }
}
Don’t just paste code, understand it!
What we’ve done in a nutshell is inherit from the DefaultControllerFactory which is what ASP.Net MVC uses out of the box to create instances of controllers every time you request one such as when browsing to a page on your web site.Then on our custom controller factory we are using Castle Windsor to resolve components. We give it a controller type and then ask it to try to find an implementation in our code. If can’t find anything we tell it to return a 404 error otherwise we ask it to create the object for us and return it.We also tap into the ReleaseController method that gets called once the controller goes out of scope and is no longer needed. We make sure that it gets removed from the IoC container to make double sure that it doesn’t keep references to objects that have been released from memory.

4)Hook up WindsorControllerFactory

We need to plug our custom controller factory in.

Go to Global.asax, and make the following changes:

using Castle.Windsor;
using Castle.Windsor.Installer;
using Spike1.WebSite.IOC;
public class MvcApplication : HttpApplication
{
  private IWindsorContainer _container;
  protected void Application_Start()
  {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
            //add the lines below
            _container = new WindsorContainer().Install(FromAssembly.This());
            ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(_container.Kernel));
  }
  protected void Application_End() { container.Dispose();   }
}
Don’t just paste code, understand it!
We’ve imported the necessary namespaces (notice that the Spike1.Website.IOC one will be different for you.We have declared a property in our MvcApplication class on Global.asax which stores our IoC Container. The reason why we declare it here is because we need to use it in both App_Start() and App_End() methods for this class.Then on App_Start we instantiated the Windsor container. We also called Install() on it which we’ll talk a bit more about later in the next section. We then told ASP.Net MVC that every time it needs to create or release a controller object that it should use our controller factory.Finally we also make sure that the IoC container is disposed of when the application ends.

5) Configure Windsor

Almost there! Now you’ve told ASP.Net MVC to use your custom controller factory and you’ve told the factory to use Castle Windsor to create them, but what you haven’t done yet is told Castle Windsor where these controller types that you are going to be declaring are located. You also need to tell Windsor which ones objects to select in case you apply any filters and also how you want them to be instantiated.

Windsor takes a very intuitive approach and uses the concept of installers. Basically, if you want to register objects you create and installer telling Windsor all of the aforementioned items and just hook it up to Windsor. When Windsor is starting up it will execute all installers and hook it all up for you automagically.

Let’s create an installer that registers our Controller objects with Castle Windsor:

using System.Web.Mvc;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
using Spike1.WebSite.Controllers;

namespace Spike1.WebSite.IOC
{
    public class ControllerInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(AllTypes.FromThisAssembly()
                                   .BasedOn<IController>()
                                   .If(Component.IsInSameNamespaceAs<HomeController>())
                                   .If(t => t.Name.EndsWith("Controller"))
                                   .Configure(c => c.LifestylePerWebRequest()));
        }
    }
}
Don’t just paste code, understand it!
We’ve created an installer which registers all controller types with Castle Windsor.We’ve told Windsor where to scan for interface types by calling AllTypes.FromThisAssembly(). We also told it what kind of interface implementations it should scan for by calling .BasedOn<IController>(). So far we’ve told it to gather all objects that implement IController in the current executing Assembly.We also have given Windsor a filter by using If() methods. We are enforcing that all controllers should be under the same namespace following HomeController as a template and we’re also reinforcing ASP.Net MVC’s convention that all controller names should end in “Controller.We then finally told Windsor how to manage our controller objects by using .Configure() and determining their lifestyle. We are setting all their lifestyles to PerWebRequest which means that every time a controller of any given type is requested Windsor will create a new instance as long as it hasn’t already been created before the Web Request is over, otherwise it will just reuse the same one.

6) Make sure your installers get executed

The good news about this step is that you’ve already done what you had to do, so this step is only to solidify your understanding.

You don’t need to plug each installer you write onto Windsor explicitly. All you need to do is to tell it where to scan for implementations of IWindsorInstaller and it’ll automatically pick them all up. So if you keep it simple and store every Installer you create on the same project, all you need to do is tell it to scan the executing Assembly like this:

_container = new WindsorContainer().Install(FromAssembly.This());

We’ve already added this code above when showing the code that you need to put in Global.asax on step 4 just to make it all copy/paste friendly in case you’re completely ignoring all the blablabla in between and copy/pasting like a manic, so there’s nothing you need to do in this step.

7)You’re done!! Nearly… Resolving your own custom dependencies

So now what you have at the moment if you’ve followed all the steps is an ASP.Net MVC application which is hooked up to Castle Windsor and builds without errors. You can use your application and continue programming as normal, but so far we haven’t got much value out of our IoC implementation since we could always get controllers created and released before out of the box, so really this was all just plumbing so we could get to the real thing: using Dependency Injection!

As you may know, Dependency Injection, in a nutshell, is the practice of creating a loosely coupled system by passing in an instance of  a generic implementation to the objects that depend on them. What this means is that instead of instantiating a CustomerRepository inside your controllers, for instance, you would pass in an ICustomerRepository on your controller’s constructor (known as “contructor injection”) and let the system decide at runtime how to create that object rather than doing it in code yourself. Enters the IoC container, more specifically in our case, Castle Windsor, which will at runtime based on all the code you put on your Installers find the appropriate object to create or release based on the interface that you passed in.

See the following example:

public class HomeController : Controller
{
  private ICustomerRepository _customerRepository;
  public HomeController(ICustomerRepository customerRepository)
  {
    _customerRepository = customerRepository;
  }
}

As you can see, we never create the CustomerRepository object ourselves, we just inject it into the HomeController and let the IoC take care of creating the object at runtime.

So, all we need to do is to make sure that we have wired up Windsor for every service (again, this is just a synonym for interface) that we create and pass around as dependencies as we develop the system. Again, you don’t need to wire them up individually. You can just scan the assembly and rely on the standard convention of matching an ISomething to Something. You would have to wire up manually anything that breaks that convention though.

I’ll post an example of an installer later on if anyone wants it.

hope this helps! 🙂