私は本格的な DDD を行っているわけではありませんが、リポジトリ パターンは魅力的であり、集約とルートの境界に沿ってリポジトリをセグメント化しようとしています。私は Entity Framework の上にリポジトリを実装しています。ここで ObjectContext は、エンティティへの変更を追跡し、SaveChanges が呼び出されたときに適切な SQL を生成するため、作業単位のスタイルを可能にします。
SaveChanges をいつ呼び出すかについて、リポジトリ内で 2 つの異なるアプローチに苦労しています。違いは、作業単位またはアクティブ レコード セマンティクスのどちらを採用しているかのようです。リポジトリ インターフェイスを次のように定義すると、次のようになります。
public interface IRepository<T>
{
T Get(int id);
IList<T> GetAll();
IQueryable<T> Query();
void Delete(T entity);
void Add(T entity);
IUnitOfWork GetUnitOfWork();
}
および IUnitOfWork になる
public interface IUnitOfWork
{
void SaveChanges();
}
Add(T entity) の実装では、次の 2 つの選択肢があるようです。
public void Add(Document entity)
{
DB.AddToDocumentSet(entity);
GetUnitOfWork().SaveChanges(); //delegates to the ObjectContext's SaveChanges
}
また
public void Add(Document entity)
{
DB.AddToDocumentSet(entity);
}
前者の場合、リポジトリの Add メソッドが各操作で SQL を送信しています。後者の場合、呼び出し元のコードは、リポジトリから作業単位を取得し、適切と思われる場合に SaveChanges を呼び出します。これにより、作業単位が異なるリポジトリにまたがることができます (各リポジトリがその構築で同じ作業単位を取得するようにしています)。
私の直感では、2 番目のアプローチの方が柔軟です。作業単位パターンを採用するということは、呼び出しコードがリポジトリーから返されたエンティティーのプロパティーを単純に更新してから、UnitOfWork.SaveChanges を呼び出すという点で、エンティティーの更新が少し良くなることも意味します。
リポジトリ パターンを使用する場合、一般的にどちらのアプローチが好まれますか?