Using the Web API Dependency Resolver with Castle Windsor's Scoped Lifetime
16 July 2012
Update: Mark Seemann has provided a solution without using the IDependencyResolver interface.
The WindsorDependencyScope from the previous post has been modified to use the Scoped lifetime
available in Castle Windsor 3.
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Web.Http.Dependencies ;
using Castle.MicroKernel.Lifestyle ;
using Castle.Windsor ;
internal sealed class WindsorDependencyScope : IDependencyScope
private readonly IWindsorContainer container ;
private readonly IDisposable scope ;
public WindsorDependencyScope ( IWindsorContainer container )
if ( container == null )
throw new ArgumentNullException ( "container" );
this . container = container ;
this . scope = container . BeginScope ();
public object GetService ( Type t )
return this . container . Kernel . HasComponent ( t ) ? this . container . Resolve ( t ) : null ;
public IEnumerable < object > GetServices ( Type t )
return this . container . ResolveAll ( t ). Cast < object >(). ToArray ();
public void Dispose ()
this . scope . Dispose ();
BeginScope is an extension method for the
IWindsorContainer type. It returns by default an instance of a
CallContextLifetimeScope type. It uses the
Call Context so it can be associated with thread pool threads and manually created threads within a single AppDomain (it does not use the Logical Call Context).
On each request the Web API calls the
GetDependencyScope extension method of the HttpRequestMessage type, which, in return, calls it’s own BeginScope method to start a new resolution scope. Using our own implementation of the IDependencyResolver interface we always return a new instance of the WindsorDependencyScope type.
internal sealed class WindsorDependencyResolver : IDependencyResolver
// 'using' Directives and other type members removed for brevity.
public IDependencyScope BeginScope ()
return new WindsorDependencyScope ( this . container );
Since we use the Scoped lifetime we need to define it also in the registration code. Then, we will always have at most one instance of each requested type per resolution scope (that is, a request).
internal sealed class WebWindsorInstaller : IWindsorInstaller
public void Install ( IWindsorContainer container , IConfigurationStore store )
container . Register ( Classes
. FromAssemblyContaining < ValuesController >()
. BasedOn < IHttpController >()
. LifestyleScoped ());
The source code can be found