Integrating MVC Web API with Castle.Windsor

Unfortunately the mechanism we use to integrate the normal MVC controllers with Castle.Windsor doesn’t work when we have to integrate Web API controllers. In order to integrate these kind of controllers as well we need to use another technique. First of all we need to create a new Dependency Resolver and a new Dependency Scope (e.g. within the usual “Infrastructure” folder):

public class CastleDependencyResolver : IDependencyResolver
{
    private readonly IKernel _kernel;
 
    public CastleDependencyResolver(IKernel kernel)
    {
        _kernel = kernel;
    }
 
    public IDependencyScope BeginScope()
    {
        return new CastleDependencyScope(_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()
    {
    }
}

public class CastleDependencyScope : IDependencyScope
{
    private readonly IKernel _kernel;
    private readonly IDisposable _disposable;
 
    public CastleDependencyScope(IKernel kernel)
    {
        _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 we have to tell MVC Framework to use our DependencyResolver instead of the default one. To do this we have to add some code (as usual) to the Application_Start() method of the global.asax file. Here is how it appears with both the normal MVC and the Web API controllers configured to be integrated with Castle.Windsor:

void Application_Start(object sender, EventArgs e)
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
 
    //Creates Castle Container
    var container = new WindsorContainer();
    container.Install(new CastleInstaller());
 
    //Creates Castle Controller Factory (MVC)
    var castleControllerFactory = new CastleControllerFactory(container);
    ControllerBuilder.Current.SetControllerFactory(castleControllerFactory);
 
    //Creates Castle Controller Factory (Web API)
    var castleDependenctResolver = new CastleDependencyResolver(container.Kernel);
    GlobalConfiguration.Configuration.DependencyResolver = castleDependenctResolver;
}

Adding all the controllers to the installer

As usual we must register all the Web API controllers (as we did with the normal MVC controllers). Here is how to register both the normal MVC and the Web API controllers with few lines of code:

//Register all the controllers
//in the current executing assembly
container.Register(Classes.FromThisAssembly().BasedOn<Controller>().LifestylePerWebRequest());
container.Register(Classes.FromThisAssembly().BasedOn<ApiController>().LifestyleScoped());
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s