我目前正在使用StructureMap将NHibernateRegistry
实例注入我的DAL,它将NHibernate配置为单个连接字符串,并为我的单用户应用程序启动Singleton FluentConfiguration
。
如何根据路由URL中的{tenant}
路由参数修改Fluent NHibernate配置以使用其他数据库?
{tenant}/{controller}/{action}/{id}
... branch1/Home/Index
和branch2/Home/Index
的请求使用相同的应用程序代码,但使用不同的数据库来检索显示的数据。
我过去通过注入每个请求TenantContext
对象来解决StructureMap和LINQ的这个问题,该对象从HttpContext
检索路由参数,它被接受为构造函数参数并指定了不同的LINQ数据背景。
然而,我怀疑NHibernate处理这个问题比我做饭更好。
NHibernateRegistry
类public class NHibernateRegistry : Registry
{
// ... private vars here
public NHibernateRegistry()
{
var cfg = Fluently.Configure()
.Database(MsSqlConfiguration
.MsSql2008.ConnectionString(c =>
c.FromConnectionStringWithKey("TenantConnectionStringKey")))
// where to inject this key?
.ExposeConfiguration(BuildSchema)
.Mappings(x =>
x.FluentMappings.AddFromAssembly(typeof(UserMap).Assembly)
For<FluentConfiguration>().Singleton().Use(cfg);
var sessionFactory = cfg.BuildSessionFactory();
For<ISessionFactory>().Singleton()
.Use(sessionFactory);
For<ISession>().HybridHttpOrThreadLocalScoped()
.Use(x => x.GetInstance<ISessionFactory>().OpenSession());
For<IUnitOfWork>().HybridHttpOrThreadLocalScoped()
.Use<UnitOfWork>();
For<IDatabaseBuilder>().Use<DatabaseBuilder>();
}
}
public static class Bootstrapper
{
public static void ConfigureStructureMap()
{
ObjectFactory.Initialize(Init);
}
private static void Init(IInitializationExpression x)
{
x.AddRegistry(new NHibernateRegistry()); // from Data project
}
}
我是NHibernate的新手,所以我不确定我的会话和配置范围。 NHibernate有内置的方法来处理这个吗?
答案 0 :(得分:0)
这对我来说是一个模块
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(x => x.FromConnectionStringWithKey("IMB"))
.Cache(c => c.UseQueryCache().QueryCacheFactory<StandardQueryCacheFactory>()
.RegionPrefix("IMB")
.ProviderClass<HashtableCacheProvider>()
.UseMinimalPuts()).UseReflectionOptimizer())
.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.Load("IMB.Data")))
.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.Load("IMB.Security")))
.ExposeConfiguration(
c => c.SetProperty("current_session_context_class", "web"))
.ExposeConfiguration(cfg => _configuration = cfg)
.BuildSessionFactory();
答案 1 :(得分:0)
问题是你真的希望你的ISessionFactory
对象是单身人士。这意味着在创建ISessionFactory
时指定连接字符串的最佳 not 。您是否尝试过创建ISessionFactory
而未指定连接字符串,然后将手动创建的连接传递给ISessionFactory.OpenSession
?
例如:
public ISession CreateSession()
{
string tennantId = GetTennantId();
string connStr = ConnectionStringFromTennant(tennantId);
SqlConnection conn = new SqlConnection(connStr);
conn.Open();
session = sessionFactory.OpenSession(conn);
}
然后告诉StructureMap调用此方法。
缺点是你现在无法在创建ISessionFactory
时构建数据库模式,但是在Web应用程序中创建数据库模式也不是一个好主意吗?