Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,128 | Comments: 45,550

filter by tags archive

Rhino Service Bus & RavenDB integration

time to read 5 min | 816 words

One of the interesting things about Rhino Service Bus is that I explicitly designed it to work nicely with Unit of Work style data access libraries. When I did that, I worked mainly with NHibernate, but it turns out that this is really easy to integrate RavenDB as well, all you need is the following message module:

public class RavenDbMessageModule : IMessageModule
    private readonly IDocumentStore documentStore;

    private static IDocumentSession currentSession;

    public static IDocumentSession CurrentSession
        get { return currentSession; }

    public RavenDbMessageModule(IDocumentStore documentStore)
        this.documentStore = documentStore;

    public void Init(ITransport transport, IServiceBus serviceBus)
        transport.MessageArrived += TransportOnMessageArrived;
        transport.MessageProcessingCompleted += TransportOnMessageProcessingCompleted;

    public void Stop(ITransport transport, IServiceBus serviceBus)
        transport.MessageArrived -= TransportOnMessageArrived;
        transport.MessageProcessingCompleted -= TransportOnMessageProcessingCompleted;

    private static void TransportOnMessageProcessingCompleted(CurrentMessageInformation currentMessageInformation, Exception exception)
        if (currentSession != null)
            if (exception == null)
        currentSession = null;

    private bool TransportOnMessageArrived(CurrentMessageInformation currentMessageInformation)
        if (currentSession == null)
            currentSession = documentStore.OpenSession();
        return false;

This is fairly simple. Register to the message arrive and message processing completed events. When a message arrive, create a new session for the consumers. When the message processing is completed, and there hasn’t been any error, we call SaveChanges, and then dispose.

The rest of it is pretty simple as well, we need to provide a BootStrapper:

public class BootStrapper : CastleBootStrapper
    IDocumentStore store;

    protected override void ConfigureContainer()
        store = new DocumentStore
            ConnectionStringName = "RavenDB"

        IndexCreation.CreateIndexes(typeof(BootStrapper).Assembly, store);

                .UsingFactoryMethod(() => RavenDbMessageModule.CurrentSession)


Which basically simply need to create the document store and expose it to the container. We get the document session from the current one (the one managed by the module).

All in all, it is quite a thing, and it takes very little time / complexity to setup.


Jason Meckley

what about Windsor's component tracking and potential memory leaks?

I thought that UsingFactoryMethod would mean Windsor would apply concerns to the components if necessary. In this case the DisposableDecommission concern. Since the session is never released from the container there would be a DisposableDecommission concern for each session. Thus a memory leak.

And wouldn't you want to register IDocumentSession as transient. Or is this covered by the threadstatic attribute within the module itself?

The only other thought I have is that resolving the current session directly from the module () => RavenDbMessageModule.CurrentSession and not the container kernel => kernel.ResolveRavenDbMessageModule.CurrentSession would mean Windsor would not apply the decommission concern.

Carlos Mendes

Ayende, why do we have to use the [ThreadStatic] attribute in the current session?

Jason Meckley

if you didn't use thread static then you would have a singleton of ISession, which was overwritten with each message consumed. thread static allows you to treat the singleton as a singleton per thread.

much the same way the session can be stored in Context.Items in a web environment.

Ayende Rahien

Jason, I am using the no tracking policy.

I am registering it as transient, yes, although this is actually manage by the thread static.

The reason that I go directly through the module is mostly because it is already static

Comment preview

Comments have been closed on this topic.


  1. The worker pattern - about one day from now

There are posts all the way to May 30, 2016


  1. The design of RavenDB 4.0 (14):
    26 May 2016 - The client side
  2. RavenDB 3.5 whirl wind tour (14):
    25 May 2016 - Got anything to declare, ya smuggler?
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats