0

私はNhibernateでStructureMapを使用しています。ツールが必要になるたびに新しいセッションを構築するように指示したいと思います。 いくつかのコードで説明しようとします (これはコンソール アプリケーションです)。

この方法でセッション ファクトリを構築します (ConnDb は接続文字列です)。

For<ISessionFactory>()
 .Singleton()
 .Use(() => new NHSessionFactory(ConnDb, true).SessionFactory);

これは、セッションを構築するために使用するコードです。

For<ISession>()
  .Singleton()
  .Use(x => x.GetInstance<ISessionFactory>().OpenSession());

セッションを破棄しないとすべてが期待どおりに機能しますが、次のようなことができるようにしたいと思います。

    using (session)
    {
        using (var tx = session.BeginTransaction())
        {
            // DO SOMETHING
            tx.Commit();
        }
    }

    using (session)
    {
        using (var tx = session.BeginTransaction())
        {
            // DO SOMETHING
            tx.Commit();
        }
    }

次のように、セッションのコードを変更しようとしました。

For<ISession>()
  .AlwaysUnique()
  .Use(x => x.GetInstance<ISessionFactory>().OpenSession());

しかし、アクティブなセッションがある場合でも、新しいセッションが作成されることに気付きました。私の状況では、サービスロケーターで ISession を解決する別のコンポーネント (Rhino.Security) を参照しています。

4

1 に答える 1

1

セッションは、クライアントではなく、セッションの作成者が破棄する必要があります。セッションを同じスコープ内で作成および破棄するようにアーキテクチャを修正することを検討する必要があります。

セッションの有効期間は、それを使用するコンポーネントに合わせて制限する必要があります。1 つのグローバル セッションを持つことにより (シングルトンの試行と同様に)、セッションはアプリケーションの存続期間中にアクセスしたすべてのエンティティへの参照を保持し、メモリを効果的に消費します。また、セッションが例外をスローした場合、それは不確定な状態になり、アプリケーション全体がダウンします。

デスクトップ アプリケーションで NHibernate を使用する方法については、MSDN マガジンの Ayende の記事を参照してください。彼のアドバイスは、あなたのシナリオにも当てはまる可能性が高いです。

StructureMap を使用したセッションの処理に関しては、Jeremy Miller がブログ投稿で、ネストされたコンテナーを使用して寿命を制御する方法について説明しています。アプリケーションが単純な場合、Jeremy の例はおそらくやり過ぎです。アプリケーションのコンポーネント/コマンドごとに 1 つのセッションを注入することに集中する必要があります。

于 2011-02-14T14:24:40.947 に答える