Managing RavenDB Document Store startup

time to read 4 min | 735 words

The RavenDB’s document store is your main access point to the database. It is strongly recommended that you’ll have just a single instance of the document store per each server you are accessing. That usually means that you have to implement a singleton, with all the double checked locking nonsense that is involved in that. I was giving a course in RavenDB last week and I stumbled upon a very nice coding pattern:

public static class Global
{
    private static readonly Lazy<IDocumentStore> theDocStore = new Lazy<IDocumentStore>(()=>
        {
            var docStore = new DocumentStore
                {
                    ConnectionStringName = "RavenDB"
                };
            docStore.Initialize();

            //OPTIONAL:
            //IndexCreation.CreateIndexes(typeof(Global).Assembly, docStore);

            return docStore;
        });

    public static IDocumentStore DocumentStore
    {
        get { return theDocStore.Value; }
    }
}

This is a very readable code, and it handles pretty much all of the treading stuff for you, without obscuring what you really want to do.

And what about when you have multiple servers? How do you handle it then? Same idea, taken one step further:

public static class Global
{
    private readonly static ConcurrentDictionary<string, Lazy<IDocumentStore>> stores = 
        new ConcurrentDictionary<string, Lazy<IDocumentStore>>();
    
    public static IDocumentStore GetDocumentStoreFor(string url)
    {
        return stores.GetOrAdd(url, CreateDocumentStore).Value;
    }

    private static Lazy<IDocumentStore> CreateDocumentStore(string url)
    {
        return new Lazy<IDocumentStore>(() =>
            {
                var docStore = new DocumentStore
                    {
                        ConnectionStringName = url
                    };
                docStore.Initialize();

                //OPTIONAL:
                //IndexCreation.CreateIndexes(typeof(Global).Assembly, docStore);

                return docStore;
            });
    }
}

This is nice, easy and the correct way to handle things.