web api controller and castle windsor lifestyle

Vagelis Ouranos

Inside a web api controller function i use two services and since they do independent stuff i want them to use different units of work (transactions).

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

From what i understand a solution is to use LifeStyleScoped but i have two problems:

  1. i want LifeStyleScoped only for this particular case and not generally
  2. i cannot find a single example of how to use LifeStyleScoped inside a controller.

Any other suggestions or code examples would be appreciated.

Edit: I didn't mention that the unitofwork is not injected explicitly in the controller. Two services are injected in the controller and these services use the unit of work that is created through castle windsor.

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) {

    }
}
Phil Degenhardt

If you are using Castle.Windsor in a Web API app, you are probably already using IDependencyResolver, which you can wire up to use Windsor's own 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();
    }
}

Web API will create a new scope for each request and dispose it after the request is finished. So if you are using this technique you can probably do away with your LifestylePerWebRequest and simply go with LifestyleScoped, thus resolving the need to have two registrations for each component.

The second challenge then is: how do you get a second independent unit of work? Clearly all of the mandatory and optional controller dependencies will implicitly be resolved within the same ILifetimeScope, so simply naively declaring a constructor dependency for a second IUnitOfWork will not work.

There are a number of ways you could do this, but if you're prepared to live with the Service Locator Anti-Pattern you could simply create your own scope like so:

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...
    }
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Castle Windsor Lifestyle for EF DbContext Needed For Logging After Web API Request

From Dev

How do I get Web API / Castle Windsor to recognize a Controller?

From Dev

Argument-bound lifestyle in Castle Windsor

From Dev

Web Api Owin Castle Windsor resolving controllers

From Dev

Why Castle Windsor's Typed Factory registered as Singleton lifestyle is Disposed?

From Dev

Lifestyle of a HttpClient in MVC4 using castle-windsor

From Dev

Windsor Castle 3.0 use IContributeComponentModelConstruction to set lifestyle to WcfPerOperation

From Dev

Can the default lifestyle of Castle Windsor registered components be changed?

From Dev

How do I specify the class instance I want my Controller's constructor to receive (when working with Web API, DI, and Castle Windsor)?

From Dev

castle windsor exception when using in selfhosted web api

From Dev

Setting different Castle Windsor lifestyle from different applications using the same installer

From Dev

Castle Windsor web.config parameters

From Dev

How can I tell the Web API / Castle Windsor routing engine to use a different database instance in my Repository?

From Dev

How do I connect the various pieces of my Web API Castle Windsor DI code?

From Dev

Simple injector lifestyle warnings for web api controllers

From Dev

Using Castle Windsor fluent API to register components implementing multiple interfaces

From Dev

Castle Windsor register an interface

From Dev

Castle windsor intercepter

From Dev

Castle Windsor Inline dependencies

From Dev

Setup Castle Windsor in MVC

From Dev

Wrapping NLOG in Castle Windsor

From Dev

Castle Windsor Xamarin PCL

From Dev

Castle Windsor: OnCreate for BaseOnDescriptor

From Dev

Conditional Resolve in Castle Windsor

From Dev

Castle Windsor Interceptor

From Dev

Multiple registrations with Castle Windsor

From Dev

Castle Windsor & Command Pattern

From Dev

Castle Windsor - registration by convention

From Dev

Castle Windsor WCFFacility compression

Related Related

  1. 1

    Castle Windsor Lifestyle for EF DbContext Needed For Logging After Web API Request

  2. 2

    How do I get Web API / Castle Windsor to recognize a Controller?

  3. 3

    Argument-bound lifestyle in Castle Windsor

  4. 4

    Web Api Owin Castle Windsor resolving controllers

  5. 5

    Why Castle Windsor's Typed Factory registered as Singleton lifestyle is Disposed?

  6. 6

    Lifestyle of a HttpClient in MVC4 using castle-windsor

  7. 7

    Windsor Castle 3.0 use IContributeComponentModelConstruction to set lifestyle to WcfPerOperation

  8. 8

    Can the default lifestyle of Castle Windsor registered components be changed?

  9. 9

    How do I specify the class instance I want my Controller's constructor to receive (when working with Web API, DI, and Castle Windsor)?

  10. 10

    castle windsor exception when using in selfhosted web api

  11. 11

    Setting different Castle Windsor lifestyle from different applications using the same installer

  12. 12

    Castle Windsor web.config parameters

  13. 13

    How can I tell the Web API / Castle Windsor routing engine to use a different database instance in my Repository?

  14. 14

    How do I connect the various pieces of my Web API Castle Windsor DI code?

  15. 15

    Simple injector lifestyle warnings for web api controllers

  16. 16

    Using Castle Windsor fluent API to register components implementing multiple interfaces

  17. 17

    Castle Windsor register an interface

  18. 18

    Castle windsor intercepter

  19. 19

    Castle Windsor Inline dependencies

  20. 20

    Setup Castle Windsor in MVC

  21. 21

    Wrapping NLOG in Castle Windsor

  22. 22

    Castle Windsor Xamarin PCL

  23. 23

    Castle Windsor: OnCreate for BaseOnDescriptor

  24. 24

    Conditional Resolve in Castle Windsor

  25. 25

    Castle Windsor Interceptor

  26. 26

    Multiple registrations with Castle Windsor

  27. 27

    Castle Windsor & Command Pattern

  28. 28

    Castle Windsor - registration by convention

  29. 29

    Castle Windsor WCFFacility compression

HotTag

Archive