Question

I am using Castle ActiveRecord in my Asp.net / MVC 2 / Multi-tenancy application with SQL Server as my backend.

For every user logging in, the app loads the corresponding DB, dynamically at run time like below:

IDictionary<string, string> properties = new Dictionary<string, string>();

    properties.Add("connection.driver_class", "NHibernate.Driver.SqlClientDriver");
    properties.Add("dialect", "NHibernate.Dialect.MsSql2005Dialect");
    properties.Add("connection.provider", "NHibernate.Connection.DriverConnectionProvider");
    properties.Add("proxyfactory.factory_class", "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");

    properties.Add("connection.connection_string", strDBConnection);

    InPlaceConfigurationSource source = new InPlaceConfigurationSource();
    source.Add(typeof(ActiveRecordBase), properties);

    ActiveRecordStarter.Initialize(new System.Reflection.Assembly[] { asm1 }, source);

The strDBConnection string comes from another small database that holds the user info, corresponding DB, etc.

Scenario:

  1. When a user logs in, his DB gets loaded, he can do his CRUD jobs -- No Probs !
  2. Another user logs in (from another remote machine) his DB gets loaded -- No Probs !
  3. Now, when the first user reads from DB, he sees new data from the second user's DB

My little understanding for this behavious is : ActiveRecordStarter is a Static object.

Could someone help me with a solution for this situation ?

The expected behaviour: each user should access his own DB only, securely, in parallel / at the same time.

Thanks a lot !

Était-ce utile?

La solution

ActiveRecordStarter.Initialize should only be called once in your app (in Application_Start in Global.asax).

To achieve what you want, create a class that inherits from NHibernate.Connection.DriverConnectionProvider:

public class MyCustomConnectionProvider : DriverConnectionProvider
{
    protected override string GetNamedConnectionString(IDictionary<string, string> settings)
    {
        return string.Empty;
    }

    public override IDbConnection GetConnection()
    {
        // Get your connection here, based on the request
        // You can use HttpContext.Current to get information about the current request
        var conn = Driver.CreateConnection();
        conn.ConnectionString = ... // Retrieve the connection string here;
        conn.Open();
        return conn;
    }
}

Then set the connection.provider property to the name of your class:

 properties.Add("connection.provider", "MyCompany.Domain.MyCustomConnectionProvider, MyCompany.AssemblyName");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top