1

NHibernate 3 で新しいプロジェクトを開始しており、WebSessionContext で CurrentSessionContext API を使用して ISession オブジェクトを管理しようとしています。

以前のプロジェクトでは、私は常にそれを自分で管理していたので、ISession オブジェクトが必要になるたびに、それを作成して HttpContext.Items コレクションに格納していました。非常に簡単ですが、この新しいプロジェクトにはネイティブ ソリューション (CurrentSessionContext) を使用するのが最適なオプションのようです。

オブジェクトを管理したときに、遅延初期化を行うことができました。つまり、すべてのリクエストではなく、必要なときにのみセッションを開くことができました。これは、必要ない可能性があり、すべてを開くことでリソース/時間を浪費するためです。時間。

CurrentSessionContext API でそれを行う簡単な方法はありますか?

これを担当する HttpModule で使用しているコードは次のとおりです。


public class ContextualSessionModule : IHttpModule
{

    public void Init(HttpApplication context)
    {
        context.BeginRequest += context_BeginRequest;
        context.EndRequest += context_EndRequest;
    }

    public void Dispose()
    {
    }

    private static void context_BeginRequest(object sender, EventArgs e)
    {
        var application = (HttpApplication)sender;
        var context = application.Context;

        BindSession(context);
    }

    private static void BindSession(HttpContext context)
    {
        // Create a new session (it's the beginning of the request)
        var session = SessionBuilderFactory.CurrentSessionFactory.OpenSession();

        // Tell NH session context to use it
        CurrentSessionContext.Bind(session);
    }

    private static void context_EndRequest(object sender, EventArgs e)
    {
        var application = (HttpApplication)sender;
        var context = application.Context;

        UnbindSession(context);
    }

    private static void UnbindSession(HttpContext context)
    {
        // Get the default NH session factory
        var factory = SessionBuilderFactory.CurrentSessionFactory;

        // Give it to NH so it can pull the right session
        var session = CurrentSessionContext.Unbind(factory);

        if (session == null) return;
        session.Flush();
        session.Close();
    }
}

編集

Diego はほぼ完璧にやり遂げましたが、私はこれについてもう少し考え、私がそのコントロールを自分で実装した主な理由を思い出しました: トランザクションです。

私はオニオン アーキテクチャの専門家なので、ドメイン オブジェクト (いつトランザクションを開始するかを知っているオブジェクト) はインフラストラクチャにアクセスできないため、トランザクションを開始できません。

これを解決するために、遅延初期化を使用し、セッションを開くときに常にトランザクションを開始します。コミットは、リクエストが終了し、例外がキャッチされなかったときに発生します。これに加えて、クエリを実行する場合でも、常にトランザクションを使用するという Ayende のアドバイスがあります。何かご意見は?

4

1 に答える 1

3

あなたの質問に直接答えているわけではありませんが、私は次のように思います:なぜですか?

セッションは軽量オブジェクトです。使用しない場合、内部構造を初期化するだけで、DB 接続などは開きません。

少しの時間/メモリを節約するために、静的オブジェクトのセッションを開くことを避けるためのいくつかの例があります(Googleのみ)。それ以外は、プロファイリングでパフォーマンスが低下していないことが示されない限り、価値がないかもしれません。

更新: トランザクションのニーズについては、uNhAddIns の CpBT 実装を参照してください。

于 2010-12-17T13:28:35.387 に答える