4

この問題を要約する2つの引用符から始めましょう。「DbContextのまとめはリークの多い抽象化です。何があっても、サービス/コントローラー層でEFに何らかの依存関係が生じることになります。」引用参照 および2番目の引用:

「DbContextクラス

Unit-Of-WorkパターンとRepositoryパターンの組み合わせを表し、データベースにクエリを実行して変更をグループ化し、変更を1つの単位としてストアに書き戻すことができます。」MSDN

リポジトリパターンでは、データベースを単純にスワップアウトできるとは言わないでください。そうではありません。成熟したアプリケーションでそれを行った人はいますか?また、リポジトリパターンがIQueryableを公開してはならないという回答もしないでください。これは、一緒に作業している人を信頼していないという別の言い方だと思います。

私はすべてカプセル化、コードカバレッジ/テスト容易性を求めていますが、EFのこの人気のあるリポジトリパターンはIQueryableを公開しているため、パターンの必要性はなくなったようです。

   public interface IRepository<T> where T : class
    {
    IQueryable<T> GetAll();
    T GetById(int id);
    IEnumerable<T> Get(Expression<Func<T, bool>> filter = null,Func<IQueryable<T>,IOrderedQueryable<T>> orderBy = null, string includeProperties = "");
    void Add(T entity);
    void Update(T entity);
    void Delete(T entity);
    void Delete(int id);
}

UOWパターンと組み合わせたリポジトリパターンの唯一の利点は次のとおりです。1。依存性注入パターンを簡単に有効にして、テスト容易性/コードカバレッジを向上させます。2。外部統合(さまざまなベンダー、Web API、データベースへのWebサービス呼び出し)に存在する複雑さをカプセル化します。 、など。)

では、MyDbContext:DbContextクラスを使用しても得られないカプセル化は何ですか?私のORMは抽象化です。確かに、UOWの作業と、追加や削除などの一般的なクエリを使用して、コントローラーの均一性をある程度得ることができますが、それは本当に努力する価値があります。私は自分の開発者が統一されていると信じることはできません。彼らが少しでもそれをやるときは、それについてOCDを取得しないでください。そして、コントローラーは必要なクエリを記述できるので、これは単体テストに直面してもうまくいきませんか?そして(さらに大きなキャップ笑)呼び出すサードパーティのAPIがある場合は、コントローラーのMyDbContextクラスでこれにアクセスできるようにすることができるので、コントローラーへの別のデータ呼び出しのように見えます。

もう一度言いますが、ORMを直接使用しないのは、データの抽象化です。

リポジトリパターンに対するいくつかの議論は次のとおりです。

http://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-repository-abstraction-layer

http://ayende.com/blog/3955/repository-is-the-new-singleton

http://lostechies.com/jimmybogard/2012/09/20/limiting-your-abstractions/

http://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/

リポジトリパターンの適切な議論は次のとおりです(ただし、十分に説得力はありません): http: //www.sapiensworks.com/blog/post/2012/10/10/Do-We-Need-The-Repository-Pattern.aspx

4

2 に答える 2

6

Ayendeがもう一度投稿するのを見たら、私はばかげていると思います。それぞれをゆっくりと見ていきましょう。

  1. GenericRepositoryの適用範囲は限られています。個人的には、ドメインリポジトリにのみ使用しており、集約ルートをシリアル化された形式で保存している場合にのみ使用しています。残りのこと(モデルの表示、レポートを読む)については、それらのモデルを要求するレイヤーのニーズに合わせて設計されたリポジトリがあります。

  2. IQueryableはほとんどクエリビルダーです。リポジトリに何かを構築する方法(IQUeryable)を指示するのではなく、リポジトリから何かを要求するだけです。IQueryableを使用している場合は、リポジトリのジョブの一部をすでに実行しています(上位層のSRPを解除します)。また、IQueryableを公開するということは、上位層がクエリの作成に使用されるpocos/entitiesについて知っている必要があることを意味します。上司が、これからWebサービスからデータを取得することを決定した場合、IQueryableエンティティとORMエンティティがいたるところに散らばっていたらどうしますか?または、RDBMSが遅すぎるので、DocumentDbを使用しましょう。はい、linqをサポートする可能性がありますが、同じエンティティを定義してもよろしいですか?

  3. 開発者を信用しないでください。レイヤーの責任を混同せず、SRP(単一責任原則)が尊重される適切なアーキテクチャを信頼します。設計している場合、たとえば、ビューで必要なものではなく、データがdbに格納される方法に従ってモデルを表示すると、密結合の問題が発生します。

  4. ORMやストレージ技術を変更する必要がないためにリポジトリを使用しない理由は、私見と同様の理由です。DIコンテナまたはインターフェイスを使用する理由は、これらのクラスが変更される可能性が低く、手動で実行できるためです。とにかく注射。

  5. リポジトリを使用すると、モデルをどこからどのように取得するかを気にする必要がなくなります。リポジトリは、ビジネスフレンドリーなセマンティクス(GetTopSellingProducts)を公開します。ormを使用すると、クエリを作成し(linqで結合やサブクエリを実行するのが大好きです)、エンティティについて知り、投影などを行う必要があります。なぜ上位層がこれらの詳細を気にする必要があるのでしょうか。それは「尋ねる、方法を教えない」原則(j / k)

結局のところ、保守可能なコードがすべてです。自分のコードを簡単に理解できるようにしたいと思います。

于 2013-01-26T08:11:20.720 に答える
3

もう一度言いますが、ORMを直接使用しないのは、データの抽象化です。

これはデータの抽象化であり、データの抽象化ではありません。

それはあなたがそれを切り替える必要がある場合にあなたのORMを抽象化することについてです。一般的なリポジトリがDbContextを介して直接提供できる機能についてではありません。EFとDbContextを切り替える必要があり、それが高度に結合されている場合は、DbContextを使用するコードのすべてのセクションを編集するか、切り替えるORMにDbContextインターフェイスを実装する必要があります。

ほとんどのアプリケーションでORMを切り替える可能性は低く、DbContextを使用することの利便性は、EFへの結合のリスクを直接上回っていると思います。ただし、アプリケーションの要件と寿命に応じて、なぜそれを実行したいのかはまだわかります。

于 2013-01-25T23:23:04.620 に答える