5

私はリポジトリパターンを実装しています。これの私の主な理由:

  • 永続化の詳細からクライアント コードを抽象化するには (Entity Framework)
  • テスト容易性をサポートする

汎用リポジトリかどうか?

私が遭遇した問題は、汎用リポジトリが必要かどうかです。メソッドは、特定のクエリを作成するIQueryable<T> Query()手段を呼び出し元のコードに提供します。ここでの問題は、これが漏れやすい抽象化であることです。Entity Framework の仕様がクライアント コードに漏れています。

ここに画像の説明を入力

  • これは単体テストにどのように影響しますか? ICustomerRepositoryこの実装で モックを作成することはできますか?

  • これは私の永続層を一掃することにどのように影響しますか? Azure Storage Tables や NHibernate と同様です。

そうしないとICustomerRepository、 や などの非常に特殊なクエリ メソッドを に実装する必要がGetIsActiveByFirstName()ありGetIsActiveByDistrict()ます。私のリポジトリクラスがさまざまなクエリメソッドでぎゅうぎゅう詰めになるので、これはとても嫌いです。このシステムには数百のモデルがあるため、作成および保守するこれらのメソッドが数百または数千になる可能性があります。

4

1 に答える 1

3

IRepository<T>柄にこだわることで比較的きれいに持つことができます。

データ アクセス層

  • EF および Core プロジェクトへの参照
  • もっているRespository<T> : IRepository<T>
  • オプションに IEFJunk 宣言がある (複数のリポジトリを使用している場合のみ)
  • コアへの参照
  • リポジトリに Context が注入される (通常はインスタンス化中)

  • 「注入」できるインターフェース
  • IRepository 宣言。EF データ型を使用しない。
  • EFへの参照なし

これで、Core のコードを参照できるようになりましたIRepository<t>。実装クラスは EF 仕様を持つことができます。しかし、これはコアからアクセスできません!

IQueryable を持つことができます。

  public interface IRepositoryBase<TPoco>{
     IQueryable<TPoco> GetListQ(Expression<Func<TPoco, bool>> predicate);
  //...

しかし、追加したいと決めた場合

 //...
 // logically exposing  IQueryable<T> Include<T>(this IQueryable<T> source, string path) from EF
 IQueryable<TPoco> IncludeNAVProp(string navToInclude);
 }

次に、リポジトリの実装

return  Context.Set<TPoco>().Include(navToInclude);

基になるプロバイダーが EF である必要があります。したがって、モックは実際の EF プロバイダーに対して行われます。

注意しない限り、EF 固有のコードです。漏出する。実際、CONCEPT「include」を持つインターフェイス IRepository は、すでに LEAKY と見なすことができます。インターフェイスから EF の仕様を除外することが、リークを回避するための鍵です。
また、1 対1で数百のテーブルをサポートできますIRepository<t>Respository<t>

于 2013-12-11T11:06:57.663 に答える