如何为多租户应用程序的每个会话初始化和持久化Castle ActiveRecordStarter?

时间:2013-04-30 22:35:04

标签: asp.net-mvc multi-tenant castle-activerecord

我在Asp.net / MVC 2 /多租户应用程序中使用Castle ActiveRecord,SQL Server作为我的后端。

对于每个登录的用户,该应用程序会在运行时动态加载相应的数据库,如下所示:

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);

strDBConnection字符串来自另一个包含用户信息,相应数据库等的小型数据库。

情景:

  1. 当用户登录时,他的数据库被加载,他可以做他的CRUD工作 - 没有Probs!
  2. 另一位用户登录(从另一台远程计算机)他的数据库被加载 - 没有Probs!
  3. 现在,当第一个用户从数据库中读取数据时,他会看到来自第二个用户的数据库的新数据
  4. 我对此行为的一点理解是:ActiveRecordStarter是一个静态对象。

    有人可以帮我解决这种情况吗?

    预期的行为: 每个用户只能安全,并行/同时访问自己的数据库。

    非常感谢!

1 个答案:

答案 0 :(得分:0)

ActiveRecordStarter.Initialize只应在您的应用中被称为一次(在Global.asax的Application_Start中)。

要实现您的目标,请创建一个继承自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;
    }
}

然后将connection.provider属性设置为您的类的名称:

 properties.Add("connection.provider", "MyCompany.Domain.MyCustomConnectionProvider, MyCompany.AssemblyName");