I have an MVC4 application using RavenDB as a datastore. The application has MVC/Web, Domain, Data, and Security layers.
I am writing custom membership and role providers that need to initialize the database and access the DocumentStore. I'm writing these class from the Security layer, and would like to use a singleton DocumentStore (set in the application), but I can't figure out how to access it.
Other, examples I see of writing custom providers for RavenDB create new DocumentStore instances within the Provider.Initialize() methods, but that seems to break the rule of having a single DocumentStore per server.
Currently, I create a single instance of the RavenDB DocumentStore in Application_Start(). I have a base controller in the MVC/Web layer that handles the DocumentStore.Session(s).
Is there a way of accomplishing this? Should I move my security logic into the MVC/Web layer to simplify things?
I came up with my own solution using a singleton pattern.
What I did was create a singleton, that exposes a public IDocumentStore property, in the data layer of my application. It utilizes a static constructor which runs upon first request for static property (executed in Application_Start), and in turn instantiates an IDocumentStore object. The initial instance is then then returned for each reference to DocStore.Instance in a base controller and in other layers of my application (like the security layer f.ex.)
public sealed class DocStore
{
protected static readonly IDocumentStore instance;
static DocStore()
{
// instantiate documentStore
instance = new DocumentStore { ConnectionStringName = Constants.ConnectionStrings.XXXXX };
instance.Initialize();
// instantiate tenants
try
{
instance.DatabaseCommands.EnsureDatabaseExists(Constants.Tenants.XXXXX);
}
catch (Exception ex)
{
//TODO: catch exception
throw ex;
}
// initialize indexed
try
{
InitializeIndexes(instance);
}
catch (Exception ex)
{
//TODO: catch exception
throw ex;
}
}
private DocStore()
{
}
public static IDocumentStore Instance
{
get { return instance; }
}
private static void InitializeIndexes(IDocumentStore store)
{
// builds all indexes defined in XXXXX.Data.dll
var dataCatalog = new CompositionContainer(new AssemblyCatalog(typeof(DocStore).Assembly));
IndexCreation.CreateIndexes(dataCatalog,
store.DatabaseCommands.ForDatabase(Constants.Tenants.XXXXX),
store.Conventions);
}
}