私はリポジトリパターンを学習しており、 Entity Framework 4.1およびCode Firstを使用したリポジトリパターン および Generic Repository Pattern-Entity Framework、ASP.NET MVC、およびUnit Testing Triangle を読んでいたEntity Frameworkでリポジトリパターンを実装します。
言って
•上位層からEFを非表示にする
•コードをテストしやすくする
理解しやすいコードをテストしやすくしますが、なぜEFを上位層から隠すのですか?
実装を見ると、エンティティフレームワークをクエリするための汎用メソッドでエンティティフレームワークをラップしているように見えます。実際にこれを行う理由は何ですか?
私は
これを正しく理解していますか?
クラスを持つDataAccessLayerを作成すると、メソッドがあります
QueryFooObject(int id)
{
..//query foo from entity framework
}
AddFooObject(Foo obj)
{
.. //add foo to entity framework
}
......
QueryBarObject(int id)
{
..
}
AddBarObject(Bar obj)
{
...
}
これもリポジトリパターンですか?
ダミーの説明は素晴らしいでしょう:)
1つのことは、テスト容易性を高め、基礎となる永続化テクノロジーと疎結合することです。ただし、集約ルートオブジェクトごとに1つのリポジトリがあります(たとえば、オーダーは集約ルートにすることができ、ドメインオブジェクトの永続性をより汎用的にするために、オーダーライン(集約ルートではない)もあります。
また、オブジェクトを管理するのがはるかに簡単になります。注文を保存すると、子アイテム(注文明細)も保存されるためです。
私はあなたがすべきだとは思わない。
Entity Frameworkはすでにデータベース上の抽象化レイヤーです。コンテキストは作業単位パターンを使用し、各DBSetはリポジトリです。この上にリポジトリパターンを追加すると、ORMの機能から離れます。
これについては、ブログの投稿で説明しました: http://www.nogginbox.co.uk/blog/do-we-need-the-repository-pattern
独自のリポジトリ実装を追加する主な理由は、依存性注入を使用してコードをよりテストしやすくするためです。
EFはすぐにテストできるわけではありませんが、注入可能なインターフェイスを使用して、EFデータコンテキストのモック可能なバージョンを作成するのは非常に簡単です。
私はここでそれについて話しました: http://www.nogginbox.co.uk/blog/mocking-entity-framework-data-context
EFをテスト可能にするためにリポジトリパターンが必要なければ、まったく必要ないと思います。
また、クエリを集中管理することも利点です。そうしないと、クエリが散らばってしまい、保守が難しくなります。
そして、あなたが言及する最初のポイント:「EFを隠す」ことは良いことです!たとえば、ロジックの保存は実装が難しい場合があります。さまざまなシナリオに最適な複数の戦略があります。特に、関連するエンティティに変更があるエンティティを保存する場合。
リポジトリを(UnitOfWorkと組み合わせて)使用すると、このロジックも集中化できます。
こちら 素敵な説明付きのビデオです。
リポジトリシステムはテストに適しています。
1つの理由は、依存性注入を使用できることです。
基本的には、リポジトリのインターフェイスを作成し、オブジェクトを作成するときにそのインターフェイスを参照します。その後、そのインターフェイスを実装する偽オブジェクトを(たとえばmoqを使用して)後で作成できます。 ninjectのようなものを使用すると、適切な型をそのインターフェイスにバインドできます。方程式から依存関係を取り除き、テスト可能なものに置き換えたばかりです。
アイデアは、テストの目的でオブジェクトの実装を簡単に交換できるようにすることです。
ここで答えにリンクを提供するのは悪いことを知っていますが、Entity Frameworkで使用する場合のRepository Patternのさまざまな利点を説明するビデオを共有したかったです。以下はyoutubeのリンクです。
https://www.youtube.com/watch?v=rtXpYpZdOzM
また、リポジトリパターンを適切に実装する方法に関する詳細も提供します。
リポジトリクラスを設計して、似たようなドメインオブジェクトを作成し、すべてのリポジトリに同じデータコンテキストを提供し、作業単位の実装を容易にする場合、リポジトリパターンは理にかなっています。以下にいくつかの不自然な例を見つけてください。
class StudenRepository
{
dbcontext ctx;
StundentRepository(dbcontext ctx)
{
this.ctx=ctx;
}
public void EnrollCourse(int courseId)
{
this.ctx.Students.Add(new Course(){CourseId=courseId});
}
}
class TeacherRepository
{
dbcontext ctx;
TeacherRepository(dbcontext ctx)
{
this.ctx=ctx;
}
public void EngageCourse(int courseId)
{
this.ctx.Teachers.Add(new Course(){CourseId=courseId});
}
}
public class MyunitOfWork
{
dbcontext ctx;
private StudentRepository _studentRepository;
private TeacherRepository _teacherRepository;
public MyunitOfWork(dbcontext ctx)
{
this.ctx=ctx;
}
public StudentRepository StundetRepository
{
get
{
if(_studentRepository==null)
_stundentRepository=new StundetRepository(this.ctx);
return _stundentRepository;
}
}
public TeacherRepository TeacherRepository
{
get
{
if(_teacherRepository==null)
_teacherRepository=new TeacherRepository (this.ctx);
return _teacherRepository;
}
}
public void Commit()
{
this.ctx.SaveChanges();
}
}
//some controller method
public void Register(int courseId)
{
using(var uw=new MyunitOfWork(new context())
{
uw.StudentRepository.EnrollCourse(courseId);
uw.TeacherRepository.EngageCourse(courseId);
uw.Commit();
}
}
アプリでファイルパスをハードコーディングしない同じ理由: 疎結合 および カプセル化 。 「c:\ windows\fonts」へのハードコードされた参照と、発生する可能性のある問題があるアプリを想像してください。パスへの参照をハードコーディングするべきではないのに、なぜ永続層への参照をハードコーディングする必要があるのですか?構成設定(または 特別なフォルダー またはOSがサポートするもの)の背後にパスを非表示にし、リポジトリの背後に永続性を非表示にします。永続性の懸念がリポジトリの背後に隠されている場合、ユニットテスト、他の環境への展開、実装の交換、ドメインオブジェクトの理由付けがはるかに簡単になります。