自分で解決策を考えている間に、この質問を世に出そうと思いました。
アプリケーションの大部分を構築した後、追加のデータベースへの読み取り/書き込みをサポートするという土壇場の要件があります (合計 2 つ、他には知られていません)。DI/IoC コンポーネントを提供する Autofac を使用して、NHibernate を使用してアプリケーションを構築しました。FWIW、これは ASP.NET MVC 2 アプリにあります。
NHibernate セッションを使用する汎用リポジトリ クラスがあります。IRepository<>
理論的には、2 番目のデータベースに渡されるセッションが適切な SessionFactory から生成される限り、この汎用リポジトリ ( ) を引き続き使用できますよね?
さて、アプリが起動すると、Autofac がそれを行います。Session と SessionFactory に関しては、次のようなモジュールがあります。
builder.Register(c => c.Resolve<ISessionFactory>().OpenSession())
.InstancePerMatchingLifetimeScope(WebLifetime.Request)
.OnActivated(e =>
{
e.Context.Resolve<TransactionManager>().CurrentTransaction = ((ISession)e.Instance).BeginTransaction();
});
builder.Register(c => ConfigureNHibernate())
.SingleInstance();
ここで、ベースの SessionFactory を返す ConfigureNHibernate() は次のようになります。
private ISessionFactory ConfigureNHibernate()
{
Configuration cfg = new Configuration().Configure();
cfg.AddAssembly(typeof(Entity).Assembly);
return cfg.Configure().BuildSessionFactory();
}
現在、これは 1 つのデータベースのみに制限されています。他の NHib シナリオでは、個別の SessionFactories のインスタンスをハッシュに押し込み、必要に応じてそれらを取得する可能性があります。メジャー リリースがかなり近づいているので、全体を再構築する必要はありません。したがって、2 つの SessionFactory を個別に構成できるように、少なくとも上記のメソッドを変更する必要があると思います。私の灰色の領域は、特定のリポジトリ (または少なくともその 2 番目のデータベースに固有のエンティティ) で使用される正しい Factory を指定する方法です。
この方法で IoC コンテナーと NHibernate を使用しているときに、このシナリオの経験がある人はいますか?
編集 構成ファイルのパスを取得し、HttpRuntime.Cache に一致する SessionFactory が存在するかどうかを確認し、まだ存在しない場合は新しいインスタンスを作成し、その SessionFactory を返す GetSessionFactory メソッドをスタブ化しました。ここで、適切な構成パスを指定する方法とタイミングを Autofac に指示する方法を突き詰める必要があります。新しいメソッドは次のようになります(Billy の 2006 年の投稿から大幅に借用):
private ISessionFactory GetSessionFactory(string sessionFactoryConfigPath)
{
Configuration cfg = null;
var sessionFactory = (ISessionFactory)HttpRuntime.Cache.Get(sessionFactoryConfigPath);
if (sessionFactory == null)
{
if (!File.Exists(sessionFactoryConfigPath))
throw new FileNotFoundException("The nhibernate configuration file at '" + sessionFactoryConfigPath + "' could not be found.");
cfg = new Configuration().Configure(sessionFactoryConfigPath);
sessionFactory = cfg.BuildSessionFactory();
if (sessionFactory == null)
{
throw new Exception("cfg.BuildSessionFactory() returned null.");
}
HttpRuntime.Cache.Add(sessionFactoryConfigPath, sessionFactory, null, DateTime.Now.AddDays(7), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.High, null);
}
return sessionFactory;
}