2

私の MVC コントローラーでは、IoC コンテナー (Ninject) を使用していますが、Entity Framework ObjectContext に関しては最適な使用方法がわかりません。

現在、私は次のようなことをしています:

using(var context = new MyObjectContext())
{
     var stuff = m_repository.GetStuff(context);
}

これは、データベース接続を可能な限り短時間開いたままにしておくという観点から、管理するための最良の方法です。

リクエストごとに Ninject を介して ObjectContext を作成すると、明らかにデータベース接続が長時間開いたままになります。

また、上記のコードは...

var stuff = m_repository.GetStuff(m_myObjectContext);

(そして、いつコンテキストを破棄しますか...?)

ObjectContext のファクトリを作成し、それを DI 経由で渡す必要がありますか? これは結合を緩めますが、(私が知っている) ObjectContext のインターフェイスを維持する簡単な手段がない場合、これはテスト容易性に本当に役立ちますか?.

より良い方法はありますか?ありがとう

4

1 に答える 1

3

これは、データベース接続を可能な限り短い時間開いたままにするという観点から管理するための最良の方法です。

リクエストごとにNinjectを介してObjectContextを作成する場合、これは明らかにデータベース接続を長時間開いたままにします。

Entity Frameworkは、各クエリの実行直後に接続を閉じます(外部から開いている接続を提供する場合を除く)。そのため、このようなことを行うための議論は成り立ちません。

以前は、ビジネスロジック(正確にはコマンドハンドラー)でコンテキスト(作成、コミット、破棄)を制御していましたが、欠点は、このコンテキストを他のすべてのメソッドに渡す必要があることです。すべての依存関係。アプリケーションロジックがより複雑になると、コードが読みにくくなり、保守しにくくなります。

そのため、作業単位(your MyObjectContext)が作成され、コミットされ、ビジネスロジックの制御外に配置されるモデルに移行しました。これにより、作業単位をすべての依存関係に挿入し、すべてのオブジェクトに同じ作業単位を再利用できます。欠点は、これによりDI構成が少し難しくなることです。確認する必要があるいくつかのこと:

  1. 作業単位は、Webリクエストに従って、または特定の範囲内で作成する必要があります。
  2. 作業単位は、要求またはスコープの最後に破棄する必要があります(ただし、処理されていない場合DbContextは、アンダーライギング接続が閉じられDbContext、ファイナライザーが実装されていないため、おそらく問題にはなりません)。
  3. 作業単位を明示的にコミットする必要がありますが、Webリクエストの最後にこれを行うことはできません。その時点では、コミットしても安全かどうかわからないためです(ビジネスロジックは例外をスローしましたが、リクエストの最後に、これが実際に発生したかどうかを正しく検出する方法はありません)。

私があなたに与えることができる1つのヒントは、コマンドハンドラーを中心にシステムのビジネスロジックをモデル化することです。これにより、トランザクション動作(作業単位をコミットし、おそらくデータベーストランザクションですべてを実行する)を処理する単一のデコレーターを定義できます。シングルポイント。このデコレータは、システム内の各ハンドラにラップすることができます。

ジェネリック型とジェネリックデコレータをNinjectに登録する方法がわからないことを認めなければなりませんが、ここStackoverflowで質問すると、おそらくすぐに答えが得られます。

于 2012-04-27T07:27:32.903 に答える