回答:
あなたは実際に正しいです。DbContext
は作業単位パターンIDbSet
の実装であり、リポジトリパターンの実装です。
リポジトリは現在非常に人気があり、使いすぎています。エンティティフレームワーク用のリポジトリの作成に関する記事が数十あるだけで誰もがそれらを使用しますが、実際にはこの決定に関連する課題については誰も説明していません。
通常、リポジトリを使用する主な理由は次のとおりです。
最初の理由は、ある種のアーキテクチャの純粋さと、上位層をEFから独立させると、後で他の永続化フレームワークに切り替えることができるという素晴らしいアイデアです。実世界でそのようなことを何回見ましたか?リポジトリはEFがデフォルトで許可するものをラップする多くの追加機能を公開する必要があるため、この理由によりEFでの作業ははるかに困難になります。
同時に、EFコードをラップすることで、コードをより適切に整理し、関心の分離ルールに従うことができます。私にとって、これはリポジトリと作業単位の唯一の真の利点になる可能性がありますが、EFでこのルールに従うと、コードのメンテナンス性と可読性が向上する可能性があることを理解する必要があります小規模なアプリケーションの場合、これは不必要に複雑になる可能性があります。
2番目の理由は部分的に正しいです。EFの大きな不利な点は、モック化が難しい堅固なアーキテクチャであるため、上位層をユニットテストする場合は、EFをラップして実装をモックできるようにする必要があります。しかし、これには、ここで説明した他の多くの結果があります。
Ayendeのブログをフォローしています。NHibernateを使用したことがあれば、おそらく彼の記事を知っているでしょう。この男は最近、NHibernateでリポジトリを使用することに対していくつかの記事を書きましたが、NHibernateはモック可能です。
IDbSet
、あなたもあなたの派生コンテキストでカスタムインターフェイスを定義することができますが、すべてのthats。コードでChangeTracker、エントリ、その他を使用すると、それらをすべてラップするために多大な労力が必要になります。
IQueryable
または受け入れるExpression<>
と、単体テストではテストできない副作用を持つモックされたコンポーネントの外部にロジックを定義します。
私も同じ問題に取り組んでいます。EFレイヤーの単体テストのモック機能は重要です。しかし、この素晴らしい記事に出くわし、派生したDbContextが汎用インターフェイスを実装し、DbSetではなくIDbSetを公開することを確認して、EF 4.1 DbContextをモック可能に設定する方法を説明しました。私はDatabase Firstアプローチを使用しているため、データベースが既に存在するため、派生したDbContextを生成するために使用するT4テンプレートを変更し、それを生成してIDbSetインターフェイスを返し、汎用インターフェイスから派生させました。そうすれば、全体を簡単にモック化でき、独自の作業単位やリポジトリパターンを実装する必要がなくなります。ジェネリックインターフェイスを使用するサービスコードを記述し、単体テストに進むと、
リポジトリを作成する理由の1つは、EntityFrameworkから別のものに、またはその逆に移動する場合に、DBSetおよびDbContextの実装を非表示にすることができるようにするためです。
たとえば、NHibernateを使用していて、そのフレームワークへのすべての呼び出しをリポジトリクラス内にラップしました。彼らは取得が「汎用」になるためにIEnumerableを返し、私のリポジトリには標準のCRUD操作(更新、削除など)があります。Entity Frameworkに長い間移動しました。そうすることで、ViewModelクラス以降は何も変更する必要がありませんでした。それらはリポジトリを指しているため、リポジトリの内部を変更するだけで済みました。これにより、移行時の生活がはるかに簡単になりました。
(私はISeriesに接続しているため、NHibernateを使用しましたが、当時、ISeriesでEFを使用したコスト効果の高い実装はありませんでした。利用可能な唯一のものは、DB2ConnectのIBMに12,000ドルを支払うことでした)