2012-04-18 21 views
1

リポジトリパターンを使用してASP.NETアプリケーションを開発する場合、それぞれのメソッドは、それぞれのメソッドに対してusingブロックを使用して新しいエンティティコンテナインスタンス(コンテキスト)を作成するか、リポジトリ自体が破棄されるまで、リポジトリメソッドで使用するコンテナのクラスレベル/プライベートインスタンスを作成しますか?私が以下に留意する以外に、利点/欠点は何ですか?私が見ていないこれらのそれぞれの利点を組み合わせる方法はありますか?あなたのレポジトリはIDisposableを実装していますので、レポのインスタンス用のブロックを使用して作成できますか?ASP.NET MVC - Entity Frameworkを使用したリポジトリパターン

複数の容器(対単)

利点:

  • 自動閉鎖/配置(使用ブロックの最後に閉じられます)であることからの接続を防止することができます。
  • 特定のビュー/ビューモデルに必要なものと少ない往復だけをメモリに格納するように指示します(遅延ロードしようとすると接続エラーが発生します)。

短所:子エンティティの

  • アクセスコントローラ/ビューは、あなたと呼ばれるものに限定されている範囲内(インクルード)の多くから収集した情報を表示するダッシュボード指数のようなページの場合
  • テーブル(多くの異なるリポジトリメソッド呼び出し)では、多くのエンティティコンテナを作成して処理するオーバーヘッドを追加します。
+0

トピックオフですか?真剣に?私は建設的ではないとクローズすることができました(それについても反対しますが、 "オフトピック"よりも確かに正確です) –

答えて

2

リポジトリでコンテキストをインスタンス化する場合、常にローカルで行い、usingステートメントでラップする必要があります。

依存性注入を使用してコンテキストを挿入する場合は、要求が完了したときにコンテキストでdisposeを呼び出すようにDIコンテナに処理させます。

ガベージコレクションが発生するまでコンテキストリソースを破棄しないため、コンテキストをクラスメンバーとして直接インスタンス化しないでください。その場合は、コンテキストを破棄するためにIDipsosableを実装し、リポジトリを適切に使用しているものがリポジトリを適切に廃棄していることを確認する必要があります。

+0

リポジトリクラス自体を破棄して(リポジトリの 'Dispose'メソッドにコンテキストを配置し)、メンバとしてコンテキストを使って安全にクラスを使用することができます。彼は質問にすでにこれを示しています: "*あなたのレポジトリはIDisposableを実装していますか?レポのインスタンスのブロックを使って作成できますか?" – Slauma

+0

@Mystere素晴らしいレスポンス - 私はこの目的でDIを使用することを考えたことがないそれは完全にそれに適しているようだが。シンプルなソリューション、ありがとう! – Keith

0

私は個人的に私のリポジトリのクラスレベルに自分のコンテキストを入れます。リポジトリパターンの明確な利点は、リポジトリを簡単に交換して、別のバックエンドを利用できることです。覚えておいてください - リポジトリパターンの目的は、クライアントにバックデータを提供するインタフェースを提供することです。データソースを切り替える場合や、(依存関係注入によって)新しいデータソースをオンザフライで提供したい場合は、メソッドごとのレベルでこれを行うと、はるかに難しい問題が発生します。

MicrosoftのMSDNサイトには、repository patternという良好な情報があります。うまくいけば、これはいくつかのことを明確にするのに役立ちます

+0

残念ながら、これはあなたのコンテキストでDisposeが呼び出されないことを意味します。ガベージコレクタが掃除をするまで、接続(使用中に相当量のメモリが必要)が発生します。これは、使用ブロックでコンテキストを常にラップして、できるだけ早く処理されるようにするためです。 –

+0

@MystereMan - 良い点ですが、私は自分の投稿内で育った他の問題をどのように乗り越えますか? (今では、開発/コードオーバーヘッドを大幅に増やす1つの方法ごとに設定する責任があります。)私は個人的に他の方法では見たことがありません。 (私が正しいとは限りませんが、それは私にもっと懐疑的です。) – JasCav

+0

私はあなたの2番目の問題を理解していません。依存関係注入を使用する場合は、DIコンテナがdisposeを呼び出して処理するようにします。クラスは、DIを使用して独自のオブジェクトをインスタンス化している場合と、別の方法で設計されています。それは、より多くの作業を切り替えるかもしれませんが、それはあなたがDIで始めるべきである理由です。 –

0

私はすべての4つのポイントに反対:(使用ブロックの最後に 閉鎖する)自動閉鎖/配置されてからの接続を防止

私の意見では、メソッドレベル、リポジトリインスタンスレベル、または要求レベルでコンテキストを処理するかどうかは関係ありません。 (にはがあります.ステートメントでリポジトリメソッドをラップするか、(提案した)リポジトリクラスにIDisposableを実装し、usingにリポジトリインスタンスをラップするかコントローラのコンストラクタでリポジトリをインスタンス化し、コントローラークラスのオーバーライドに配置するか、要求が開始されたときにコンテキストをインスタンス化し、要求が終了したときにそれを二分する(いくつかの依存性注入コンテナによってこの作業を行う)。)なぜコンテキストを「自動廃棄」する必要がありますか?デスクトップアプリケーションでは、数時間にわたって開いている可能性のあるウィンドウ/ビューごとのコンテキストを持つことが可能であり、一般的です。

あなたは 特定のビュー/のviewmodelため、少ないラウンドトリップ(あなたは怠惰なロードしようと何のための 接続エラーになります)に必要なものをメモリに引っ張るだけに力を支援します。

正直言って、私はレイジーローディングを完全に無効にすることでこれを強制します。クライアントとサーバーとの接続が切断されているWebアプリケーションでは、遅延ロードのメリットはありません。コントローラのアクションでは、ロードする必要があることを常に知っており、熱心なロードや明示的なロードを使用できます。メモリオーバーヘッドを回避し、パフォーマンスを向上させるために、EFはクライアントのWebページの変更をとにかく追跡できないため、GET要求の変更追跡を常に無効にすることができます。コントローラ/ビュー内の子エンティティの

のアクセスは、あなたが何と呼ばれる に制限されている(インクルード)あなたがunwished驚きを持っていないので、むしろ不利よりも有利である

怠惰な読み込み。後でコントローラのアクションで子エンティティを設定する必要がある場合は、条件によっては、同じコンテキストまたは新しいコンテキストでも、追加のリポジトリメソッド(LoadNavigationPropertyなど)を使用して読み込むことができます。 多くのテーブル(多くの異なるリポジトリメソッドの呼び出し)から収集した情報を表示するダッシュボード指数のようなページの場合

、我々は多くのエンティティコンテナを作成し、配置する オーバーヘッドが追加されます。

文脈を作成する - そして私たちが数百または数千のインスタンスについて話しているとは思わない - は安価な操作です。私は実際には役割を果たさない非常に理論的なオーバーヘッドと呼んでいます。

私はWebアプリケーションで言及したアプローチと3つ目のオプションを使用しました。つまり、要求ごとに単一のコンテキストを作成し、コントローラアクションで必要なすべてのリポジトリ/サービスに同じコンテキストを注入します。彼らは3人とも私のために働いた。

もちろん、複数のコンテキストを使用する場合は、複数のコンテキストにエンティティを関連付けないように、同じ作業単位内ですべての作業を実行するように注意する必要があります。このような状況を避けるのは通常問題ではありませんが、特にPOST要求を処理する場合にはもう少し注意が必要です。

私は最近、コンテキストが非常に狭いというメリットがないため、要求処理ごとに複数の単一作業単位を使用する必要がないため、要求ごとにコンテキストを使用します。私が何らかの理由で複数のコンテキストを必要とするなら、私はいつも要求の「デフォルトコンテキスト」の代わりに独自のコンテキストで動作する特殊なメソッドを作成できます。

+0

ここでは、デスクトップアプリケーションではなく、Webアプリケーションについて説明しています。デスクトップアプリケーションには通常、豊富なリソースがあり、何時間もコンテキストを開いたままにすることができます。ウェブアプリケーションは、サーバーがどの程度の負荷を受けるかわからないため、できるだけ早くリソースを解放する必要があります。 Webアプリケーションは、デスクトップアプリケーションとは基本的に異なるリソース管理要件を持っています。 –

+0

@MystereMan:要求が完全に処理される前に、Webプロセスがリクエストで使用されたリソースを解放するかもしれないと言っていますか?私は、1つのリクエストよりも長い時間、コンテキスト(または複数のコンテキスト)を開いたままにするとは言いませんでした。私はあなたの批判的発言を理解していません。 – Slauma

+0

コンテキストをクラスレベルに置くと、要求が完了したときにコンテキストが破棄されません。要求はもはやそれを使用していなくても、ガーベッジ・コレクションが発生するまで、リソースおよび可能であれば接続を消費します。 DIを使用してコンテキストを注入すると、DIコンテナはリクエストの最後にdisposeを呼び出すことができます。あるいは、オブジェクトを直接インスタンス化する場合は、usingステートメントでラップしてリソースを解放する必要があります。それ。 –

関連する問題