Web api controller and castle windsor style

Inside the web api controller function, I use two services, and since they do independent things, I want them to use different units of work (transactions).

All necessary components (unit of work, repositories) are entered through the windsor of the castle using LifestylePerWebRequest.

From what I understand, the solution is to use LifeStyleScoped, but I have two problems:

  • I want LifeStyleScoped just for this particular case, and not at all
  • I can not find any examples of using LifeStyleScoped inside the controller.

Any other suggestions or code examples would be appreciated.

Edit: I did not mention that unitofwork is not explicitly entered into the controller. Two services are entered into the dispatcher, and these services use the unit of work that is created through the Windsor Castle.

public class SomeController : ApiController
{
    private readonly IService _service1;
    private readonly IService _service2;

    public SomeController (IService service1, IService service2)
    {
        _service1= service1;
        _service2= service2;
    }

    public IHttpActionResult SomeAction() 
    {
        _service1.DoSomething();
        _service2.DoSomething();
    }
}

public Service : IService 
{
    public Service(IUnitOfWork uow) {

    }
}
+4
source share
1 answer

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() 
    {
        // Get a second UoW
        using (var separatelyScopedResolver = GlobalConfiguration.Configuration.DependencyResolver.BeginScope())
        {
            var anotherUoW = separatelyScopedResolver.GetService(typeof (IUnitOfWork));
            // Do something with this UoW...
            anotherUoW.Save();
        }

         // Do something with the default UoW...
         _uow.Save();

         // Et cetera...
    }
}
+4

All Articles