Autofac が NHibernate ISession インスタンス (ASP.NET MVC アプリケーションの場合) の管理にどのように役立つかに関するヒントやベスト プラクティスはありますか?
2 に答える
NHibernate セッションの処理方法については、あまり詳しくありません。とは言っても、Autofac は優れたインスタンス ライフタイム処理 (スコーピングと決定論的破棄) を備えています。関連するリソースには、この記事とこの質問があります。あなたは ASP.Net MVC の世界にいるので、MVC の統合についても調べてください。
この点を説明するために、Autofac ファクトリ デリゲートとOwned
ジェネリックを使用してインスタンスの有効期間を完全に制御する方法の簡単なサンプルを次に示します。
public class SomeController
{
private readonly Func<Owned<ISession>> _sessionFactory;
public SomeController(Func<Owned<ISession>> sessionFactory)
{
_sessionFactory = sessionFactory;
}
public void DoSomeWork()
{
using (var session = _sessionFactory())
{
var transaction = session.Value.BeginTransaction();
....
}
}
}
これを機能させるためのコンテナのセットアップは非常に簡単です。Func<>
and型を取得するために何もする必要がないことに注意してくださいOwned<>
。これらは Autofac によって自動的に利用可能になります。
builder.Register(c => cfg.BuildSessionFactory())
.As<ISessionFactory>()
.SingleInstance();
builder.Register(c => c.Resolve<ISessionFactory>().OpenSession());
更新:ここでの私の推論は、この NHibernate チュートリアルによると、セッション インスタンスの有効期間は「作業単位」の有効期間でなければならないということです。したがって、セッション インスタンスの作成時とセッションの破棄時の両方を制御する何らかの方法が必要です。
AutofacFunc<>
では、型の代わりに a を直接要求することで、この制御を取得します。使用しないFunc<>
場合は、コントローラー インスタンスを作成する前にセッション インスタンスを事前に作成する必要があります。
次に、Autofac のデフォルトでは、インスタンスにはコンテナーの有効期間があります。作業単位が完了したらすぐにこのインスタンスを破棄する権限が必要であることがわかっているため、Owned
インスタンスを要求します。この場合、所有されているインスタンスを破棄すると、基になるセッションがすぐに破棄されます。
編集:Autofacのように聞こえ、おそらく他のコンテナは有効期間を正しくスコープできます。その場合は、それを行ってください。
IoC コンテナーを使用してセッションを直接管理することはお勧めできません。セッションの有効期間は、作業単位 (トランザクション境界) に対応している必要があります。Web アプリケーションの場合、これはほぼ確実に Web リクエストの存続期間になります。
これを実現する最も一般的な方法は、リクエストの開始時にセッションを作成してトランザクションを開始し、リクエストの終了時にコミットする HttpModule を使用することです。HttpModule にセッションを HttpContext.Items コレクションに登録させます。
IoC コンテナーでは、HttpContextSessionLocator のようなものを ISessionLocator に対して登録できます。
一般的なエラー処理で現在のセッションを特定し、トランザクションを自動的にロールバックする必要があることに注意してください。そうしないと、作業単位の半分をコミットすることになる可能性があります。