web-dev-qa-db-ja.com

EF 4.1の汎用リポジトリーのポイント

DbContext、DbSet、および関連するインターフェイスをさらに掘り下げていくと、これらの実装の周りに別個の「汎用」リポジトリを実装する必要があるのはなぜだろうか。

DbContextとIDbSetが必要なすべてを実行し、DbContext内に「作業単位」を含めるように見えます。

私はここで何かを見逃していますか、それとも人々は理由なしに別の依存関係の層を追加することを楽しんでいるようですか?.

145
Code Jammr

あなたは実際に正しいです。 DbContextは作業単位パターンの実装であり、IDbSetはリポジトリパターンの実装です。

リポジトリは現在非常に人気があり、使い古されています。エンティティフレームワークのリポジトリの作成に関する記事が多数あるという理由だけで、誰もがこれらを使用していますが、この決定に関連する課題を実際に説明している人はいません。

通常、リポジトリを使用する主な理由は次のとおりです。

  • 上位層からEFを非表示
  • コードをテストしやすくする

最初の理由は、何らかのアーキテクチャ上の純度と、EFに依存しない上位レイヤーを作成すると、後で他の永続化フレームワークに切り替えることができるという素晴らしいアイデアです。現実の世界でそのようなものを見たのは何回ですか?この理由により、EFはデフォルトでEFが許可する機能をラップする多くの追加機能を公開する必要があるため、EFでの作業が非常に難しくなります。

同時に、EFコードをラップすると、コードをより適切に整理し、関心の分離ルールに従うことができます。私にとってこれはリポジトリと作業単位の唯一の本当の利点になりますが、EFを使用してこのルールに従うと、コードの保守性と可読性が向上する可能性があることを理解する必要がありますが、アプリケーションを作成する最初の努力でははるかに高くなり、小規模なアプリケーションの場合、これは不必要に複雑になる可能性があります。

2番目の理由は部分的に正しいです。 EFの大きな欠点は、ほとんどモックできないリジッドアーキテクチャであるため、上位層を単体テストする場合は、実装をモックできるようにEFをラップする必要があります。しかし、これには here で説明した他の多くの結果があります。

Ayendeのブログ に従います。 NHibernateを使用したことがあるなら、おそらく彼の記事を知っているでしょう。この男は最近、NHibernateでリポジトリを使用することに対していくつかの記事を書きましたが、NHibernateの方がずっとまねができます。

202
Ladislav Mrnka

私は同じ問題に取り組んでおり、EFレイヤーの単体テストのモック可能性が重要です。しかし、派生したDbContextがジェネリックインターフェイスを実装し、DbSetの代わりにIDbSetを公開することにより、EF 4.1 DbContextをモック可能に設定する方法を説明するこの素晴らしい記事を見つけました。 Database Firstアプローチを使用しているため、データベースが既に存在するため、派生DbContextの生成に使用されるT4テンプレートを変更して、ジェネリックインターフェイスから派生するだけでなく、IDbSetインターフェイスを返すように生成しました。そうすれば、全体を簡単にモックでき、独自の作業単位やリポジトリパターンを実装する必要はありません。汎用インターフェイスを使用するサービスコードを記述するだけで、単体テストに行くときは、汎用インターフェイスを特定のテストデータでモックするだけで準備完了です。

http://refactorthis.wordpress.com/2011/05/31/mock-faking-dbcontext-in-entity-framework-4-1-with-a-generic-repository/

21
Kendall Bennett

リポジトリを作成する理由の1つは、EntityFrameworkから別の場所に移動する場合、またはその逆の場合にDBSetおよびDbContextの実装を非表示にできるためです。

たとえば、NHibernateを使用していて、そのフレームワークへのすべての呼び出しをリポジトリクラス内にラップしました。取得が「ジェネリック」であるためIEnumerableを返し、私のリポジトリには標準のCRUD操作(更新、削除など)があります。 Entity Frameworkに移行してからずっと経ちました。そうすることで、ViewModelクラスまたはそれ以上がリポジトリを指すため、変更する必要はありませんでした。リポジトリの内部を変更するだけでした。これにより、移行時の生活がずっと楽になりました。

(私はISeriesに接続しているため、NHibernateを使用しましたが、その時点でISeriesでEFを使用したコストに影響する実装はありませんでした。DB2Connectに対して12,000ドルをIBMに支払うだけでした)

5
user134363