Windsor RavenDb session management under NServiceBus

I use NServiceBus (3.2.2), RavenDB (1.2.2017-Unstable) and Windsor (3.0.0.4001) in the MVC 4 project.

I have an IHandleMessages class that processes 3 different messages and needs an IDocumentSession and therefore defines a property such as:

public IDocumentSession DocumentSession { get; set; }

I copied the implementation of RavenDbUnitOfWork from NServiceBus

I registered IDocumentStore, IDocumentSession, and IManageUnitsOfWork in the Windsor container as follows:

container.Register(
            Component
                .For<IManageUnitsOfWork>()
                .ImplementedBy<RavenUnitOfWork>()
                .LifestyleTransient()
            );
container.Register(
            Component
                .For<IDocumentStore>()
                .UsingFactoryMethod(k => DocumentStoreHolder.DocumentStore)
                .LifestyleSingleton(),
            Component
                .For<IDocumentSession>()
                .UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession())
                .LifestyleTransient()
            );

NServiceBus is configured to use my container:

Configure.With()
         .CastleWindsorBuilder(container);

I ran into a problem that UnitOfWork and the message handler get different instances of DocumentSession. This means that objects stored in the session in the message handler are not saved, since SaveChanges () is called on another DocumentSession.

, concurrency/ RavenDb, () DocumentSession, .

Update:

, IDocumentSession Windsor, Scope, :

Component
    .For<IDocumentSession>()
    .UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession())
    .LifestyleScope()

, MVC, , , BeginScope().

+5
3

, .

+4

, nservicebus - asp.net mvc IDocumentSession .

ASP.NET MVC PerWebRequest, NServiceBus .

To do this, I used the hybrid lifestyle code in the Castle contrib project: https://github.com/castleprojectcontrib/Castle.Windsor.Lifestyles/tree/master/Castle.Windsor.Lifestyles

When called from an ASP.NET context, a WebRequestScopeAccessor is used. For NServicebus, you need a LifetimeScopeAccessor. This is not in the Contrib project, but it is easy to add:

public class HybridPerWebRequestLifetimeScopeScopeAccessor : HybridPerWebRequestScopeAccessor
{
    public HybridPerWebRequestLifetimeScopeScopeAccessor()
        : base(new LifetimeScopeAccessor())
    {
    }
}

And in your registration code you need something like:

container.Register(Component.For<IDocumentSession>().LifestyleScoped<HybridPerWebRequestLifetimeScopeScopeAccessor>().UsingFactoryMethod(() => RavenDbManager.DocumentStore.OpenSession()));

And here is the implementation for Rhino Service Bus i, used before switching to nservicebus:

https://gist.github.com/4655544

0
source

All Articles