「リポジトリ」という用語は、マーティン・ファウラーの著書「エンタープライズアプリケーションアーキテクチャのパターン」で「リポジトリパターン」が説明されている方法で一般的に考えられていると思います。
リポジトリは、ドメインとデータマッピングレイヤーの間を仲介し、メモリ内のドメインオブジェクトコレクションのように機能します。クライアントオブジェクトは、宣言的にクエリ仕様を作成し、満足のためにリポジトリに送信します。オブジェクトは、オブジェクトの単純なコレクションからの場合と同様に、リポジトリに追加したり、リポジトリから削除したりできます。リポジトリによってカプセル化されたマッピングコードは、バックグラウンドで適切な操作を実行します。
表面的には、Entity Frameworkはこれらすべてを実現し、リポジトリの単純な形式として使用できます。ただし、リポジトリには、単なるデータ層の抽象化以上のものが存在する可能性があります。
EricEvansによる「 DomainDrivenDesign」という本によると、リポジトリには次の利点があります。
- 永続オブジェクトを取得し、ライフサイクルを管理するための単純なモデルをクライアントに提示します
- これらは、アプリケーションとドメインの設計を永続化テクノロジー、複数のデータベース戦略、さらには複数のデータソースから切り離します。
- オブジェクトアクセスに関する設計上の決定を伝達します
- これらは、単体テスト(通常はメモリ内のコレクションを使用)のために、ダミーの実装を簡単に置き換えることができます。
最初のポイントは上記の段落とほぼ同じであり、EntityFramework自体がそれを簡単に実現できることは容易に理解できます。
EFが2番目のポイントも達成すると主張する人もいます。ただし、通常、EFは、各データベーステーブルをEFエンティティに変換し、それをUIに渡すために使用されます。データアクセスのメカニズムを抽象化している可能性がありますが、舞台裏でリレーショナルデータ構造を抽象化することはほとんどありません。
主にデータ指向の単純なアプリケーションでは、これは重要なポイントではないように思われるかもしれません。しかし、アプリケーションのドメインルール/ビジネスロジックがより複雑になるにつれて、よりオブジェクト指向になりたいと思うかもしれません。データのリレーショナル構造に、ビジネスドメインにとって重要ではないが、データストレージの副作用である特異性が含まれていることは珍しくありません。このような場合、永続性メカニズムを抽象化するだけでなく、データ構造自体の性質も抽象化するだけで十分ではありません。EFだけでは一般的にそれを行うのに役立ちませんが、リポジトリ層は役立ちます。
3番目の利点については、EFは(DDDの観点から)何もしません。通常、DDDはリポジトリを使用して、データの永続性のメカニズムを抽象化するだけでなく、特定のデータにアクセスする方法に関する制約を提供します。
また、トラバーサルで検索する方が便利な永続オブジェクトのクエリアクセスも必要ありません。たとえば、PersonオブジェクトからPersonのアドレスを要求できます。そして最も重要なのは、AGGREGATEの内部にあるオブジェクトは、ルートからのトラバーサルを除いてアクセスが禁止されていることです。
つまり、データベースにAddressテーブルがあるという理由だけで、「AddressRepository」はありません。デザインがこの方法でAddressオブジェクトにアクセスする方法を管理することを選択した場合、PersonRepositoryは、デザインの選択を定義および適用する場所です。
また、DDDリポジトリは通常、ドメインデータのセットに関連する特定のビジネスコンセプトがカプセル化されている場所です。OrderRepositoryには、Ordersの特定のサブセットを返すOutstandingOrdersForAccountというメソッドが含まれる場合があります。または、CustomerリポジトリにPreferredCustomerByPostalCodeメソッドが含まれている場合があります。
Entity FrameworkのDataContextクラスは、リポジトリ抽象化レイヤーが追加されていないと、このような機能には適していません。これらは、DDDが仕様と呼ぶものに対して適切に機能します。これは、式に対してデータを評価し、一致を返す単純なメソッドに送信される単純なブール式である可能性があります。
4番目の利点については、データコンテキストの代わりに使用できる戦略があると確信していますが、リポジトリにラップすると非常に簡単になります。
「作業単位」に関して、DDDの本は次のように述べています。
トランザクション制御はクライアントに任せます。REPOSITORYはデータベースに挿入およびデータベースから削除しますが、通常は何もコミットしません。たとえば、保存後にコミットしたくなりますが、クライアントにはおそらく、作業単位を正しく開始してコミットするためのコンテキストがあります。REPOSITORYが手を離すと、トランザクション管理が簡単になります。