Using Castle Windsor with Web API (ApiController)

By | August 27, 2014

Yesterday we started to use API Controllers and wouldn’t it be nice if we can use some inversion of control (IoC) making it extensible and reusable.  For this article you will be noticing I am using S#arp Architecture where IoC is already implemented via Castle Windsor so all I need to do is add the components needed so that the API controllers would work with the queries we already built.  Having said that you can also use this without S#arp (ie your normal MVC Application) and its a similar implementation.

There are a lot of ways to integrate a container with Web API (ApiController) but since in most of my projects we are using Castle this article will be all about integrating Web API with Castle Windsor.

Lets start with the integration points to Web API which are the IDependencyResolver and IDependencyScope interfaces.  IDependencyResolver and other interfaces might be named the same as the one in MVC but don’t be confused about it as they are in different namespaces and it is not the same one used in MVC.

1 IDependencyResolver


So what is this IDependencyResolver? Basically it represents a dependency injection container which is used to resolve everything outside a request scope.  To simplify, it just means all interfaces of your WebApi are resolved using this.  So how does it look like in code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http.Dependencies;
using Castle.MicroKernel;
 
internal class DependencyResolver : System.Web.Http.Dependencies.IDependencyResolver
{
    private readonly IKernel kernel;
 
    public DependencyResolver(IKernel kernel)
    {
        this.kernel = kernel;
    }
 
    public IDependencyScope BeginScope()
    {
        return new DependencyScope(kernel);
    }
 
    public object GetService(Type type)
    {
        return kernel.HasComponent(type) ? kernel.Resolve(type) : null;
    }
 
    public IEnumerable<object> GetServices(Type type)
    {
        return kernel.ResolveAll(type).Cast<object>();
    }
 
    public void Dispose()
    {
    }
}

If you closely look at the code the GetService method returns null if the component is unavailable this ensures the default implementation will be used.

Now on the start of the request, a dependency scope is created using the BeginScope method which is implemented by IDependencyScope then when the request ends its is then Disposed allowing us to implement a Resolve / Release pattern using Castle Windsor.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http.Dependencies;
using Castle.MicroKernel;
using Castle.MicroKernel.Lifestyle;
 
public class DependencyScope : IDependencyScope
{
    private readonly IKernel kernel;
 
    private readonly IDisposable disposable;
 
    public DependencyScope(IKernel kernel)
    {
        this.kernel = kernel;
        disposable = kernel.BeginScope();
    }
 
    public object GetService(Type type)
    {
        return kernel.HasComponent(type) ? kernel.Resolve(type) : null;
    }
 
    public IEnumerable<object> GetServices(Type type)
    {
        return kernel.ResolveAll(type).Cast<object>();
    }
 
    public void Dispose()
    {
        disposable.Dispose();
    }
}

Now this is how we implement the contract to install the components in the container.
Usually I separate classed by contract type so in this instance we create a class called WebApiInstaller.


2 WebApiInstaller

using System.Web.Http;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
 
public class WebApiInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(
            Classes
                .FromThisAssembly()
                .BasedOn<ApiController>()
                .LifestyleScoped()
            );
    }
}

If you notice the last descriptor is Lifestyle scoped, what this does is to set the component lifestyle to scoped per explicit scope, meaning each ApiController registered are released at the end of request when the dependency scope ends as seen on the Dispose Method of the DependencyScope class.

Now lets register that on your global.asax

If your currently using Castle Windsor on your vanilla MVC project or S#arp MVC website then just add the following codes below on the last line of InitializeServiceLocator method


GlobalConfiguration.Configuration.DependencyResolver = new CastleWindsor.DependencyResolver(container.Kernel);

So it should look like this

3 Global asax entry

If not just put copy and paste this on your Applicaiton_Start

var container = new WindsorContainer();
container.Install(FromAssembly.This());
GlobalConfiguration.Configuration.DependencyResolver = new CastleWindsor.DependencyResolver(container.Kernel);
Recommended

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.