3

私は本格的な 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 を呼び出すという点で、エンティティーの更新が少し良くなることも意味します。

リポジトリ パターンを使用する場合、一般的にどちらのアプローチが好まれますか?

4

1 に答える 1

2

それは、あなたが述べていない障害モードの要件によって異なります。これは主に、作業単位中に発生する障害を処理する方法の問題です。基本的には 2 つの選択肢がありますが、他にもより複雑なバリエーションが考えられます。

  1. 障害が発生するまで、作業単位中に発生したすべての変更を保存します。
  2. 障害が原因で作業単位中に発生したすべての変更をロールバックします。

最初の Add メソッドはシナリオ 1 に適し、2 番目の Add メソッドはシナリオ 2 に適しています。

シナリオ 1 では、障害が発生した時点でユーザーが再開できるように、スマートなアプリケーション コードが必要になる可能性があります。シナリオ 2 は、アプリケーション側で実装する方が簡単ですが、たとえば、失敗したときに 9 ステップのプロセスに 8 ステップだった場合、ユーザーを苛立たせる可能性があります。

于 2009-10-16T08:55:48.063 に答える