Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to setup multitenancy within an mvc 3 application with ravendb

We've an mvc3 application setup with RavenDb in the following way (with some help from NoSql with RavenDb and Asp.net MVC):

The following code is in the Global.asax

private const string RavenSessionKey = "RavenMVC.Session";
private static DocumentStore documentStore;

protected void Application_Start()
{
    //Create a DocumentStore in Application_Start
    //DocumentStore should be created once per 
    //application and stored as a singleton.
    documentStore = new DocumentStore { Url = "http://localhost:8080/" };
    documentStore.Initialise();
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);
    //DI using Unity 2.0
    ConfigureUnity();
}

public MvcApplication()
{
    //Create a DocumentSession on BeginRequest  
    //create a document session for every unit of work
    BeginRequest += (sender, args) => 
    {
      HttpContext.Current.Items[RavenSessionKey] = documentStore.OpenSession();
    }

    //Destroy the DocumentSession on EndRequest
    EndRequest += (o, eventArgs) =>
    {
        var disposable = 
                HttpContext.Current.Items[RavenSessionKey] as IDisposable;

        if (disposable != null)
            disposable.Dispose();
    };
}

//Getting the current DocumentSession
public static IDocumentSession CurrentSession
{
  get { return (IDocumentSession)HttpContext.Current.Items[RavenSessionKey]; }
}

We now want to setup the application to support multitenancy. We want to have two documentstores: one for general purpose, the system database and one for the current (logged in) tennant.

Based on our current setup how do we go about achieving this?

Edit: We now configured our application as following:

We added OpenSession(tenantid) to BeginRequest on the same documentStore (thanks to the answer below from Ayende)

var tenant = HttpContext.Current.Request.Headers["Host"].Split('.')[0];
documentStore.DatabaseCommands.EnsureDatabaseExists(tenant);
HttpContext.Current.Items[RavenSessionKey] = 
                 documentStore.OpenSession(tenant);

Because we are using Ninject for DI we added the following bindings to be sure we are using the right session:

kernel.Bind<ISession>().To<Session>().WhenInjectedInto<UserService>();
kernel.Bind<ISession>().To<TenantSession>();

kernel.Bind<IDocumentSession>().ToMethod(ctx =>        
     MvcApplication.CurrentSession).WhenInjectedInto<Session>();

kernel.Bind<IDocumentSession>().ToMethod(ctx =>  
     MvcApplication.CurrentTenantSession).WhenInjectedInto<TenantSession>();

Maybe there is a better way to configure multitenancy with ravendb and mvc?

like image 530
Andrew Avatar asked Mar 01 '12 13:03

Andrew


1 Answers

AndrewF,

You are going to have two sessions, then. One that is the defualt (OpenSession()) and the other that is for the tenant (OpenSession(TenantId))

like image 156
Ayende Rahien Avatar answered Nov 11 '22 21:11

Ayende Rahien