If you use Castle.Windsor in a web API application, you are probably already using IDependencyResolver, which you can connect to use your own Windsor scope, similar to this:
class WindsorDependencyResolver : IDependencyResolver
{
private readonly IWindsorContainer _container;
public WindsorDependencyResolver(IWindsorContainer container)
{
_container = container;
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t) ? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t).Cast<object>().ToArray();
}
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(_container);
}
public void Dispose()
{
}
}
class WindsorDependencyScope : IDependencyScope
{
private readonly IWindsorContainer _container;
private readonly IDisposable _scope;
public WindsorDependencyScope(IWindsorContainer container)
{
_container = container;
_scope = container.BeginScope();
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t) ? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t).Cast<object>().ToArray();
}
public void Dispose()
{
_scope.Dispose();
}
}
The Web API will create a new scope for each request and delete it after the request is complete. Therefore, if you use this technique, you can probably do away with your LifestylePerWebRequest and just go with LifestyleScoped, thereby deciding whether to have two registrations for each component.
: ? , ILifetimeScope, IUnitOfWork .
, Anti-Pattern Locator, :
public class SomeController : ApiController
{
private readonly IUnitOfWork _uow;
public SomeController (IUnitOfWork uow)
{
_uow = uow;
}
public IHttpActionResult SomeAction()
{
using (var separatelyScopedResolver = GlobalConfiguration.Configuration.DependencyResolver.BeginScope())
{
var anotherUoW = separatelyScopedResolver.GetService(typeof (IUnitOfWork));
anotherUoW.Save();
}
_uow.Save();
}
}