2

Active Directory と SQL データベースの両方に永続的にアクセスする必要がある DDD ベースのシステムを構築しているという独特の状況があります。最初は、これは問題ではありませんでした。これは、次のような作業単位を持つ設計がセットアップされたためです。

public interface IUnitOfWork
{
   void BeginTransaction()
   void Commit()
}

リポジトリは次のようになります。

public interface IRepository<T>
{
   T GetByID()
   void Save(T entity)
   void Delete(T entity)
}

このセットアップでは、ロードとセーブで両方のデータ ストア間のマッピングが処理されます。これは、自分で作成したためです。作業単位はトランザクションを処理し、リポジトリが永続化のために使用する Linq To SQL データ コンテキストを含みます。Active Directory の部分は、インフラストラクチャに実装されたドメイン サービスによって処理され、各 Save() メソッドのリポジトリによって使用されました。Save() は、すべてのデータベース操作を行うためにデータ コンテキストと対話する役割を果たしました。

現在、これをエンティティ フレームワークに適応させ、POCO を活用しようとしています。理想的には、ドメイン オブジェクトはオブジェクト コンテキストによって追跡されているため、Save() メソッドは必要ありません。作業単位に Save() メソッドを追加して、オブジェクト コンテキストに変更を保存させるだけで済みます。新しいオブジェクトをコンテキストに登録します。新しい提案されたデザインは、次のようになります。

public interface IUnitOfWork
{
   void BeginTransaction()
   void Save()
   void Commit()
}

public interface IRepository<T>
{
   T GetByID()
   void Add(T entity)
   void Delete(T entity)
}

これにより、エンティティ フレームワークに関するデータ アクセスの問題は解決されますが、Active Directory 統合に関する問題は解決されません。以前はリポジトリの Save() メソッドにありましたが、現在はホームがありません。作業単位は、エンティティ フレームワークのデータ コンテキスト以外は何も認識しません。このロジックはどこに行くべきですか?この設計は、エンティティ フレームワークを使用するデータ ストアが 1 つしかない場合にのみ機能すると主張します。この問題に最善のアプローチをする方法はありますか? このロジックをどこに置くべきですか?

4

3 に答える 3

4

これを投稿してから学んだことをフォローアップしたいと思いました。リポジトリ パターンに忠実であり続けるつもりなら、それが保持するデータ ストアは問題ではないようです。2 つのデータ ストアがある場合は、同じリポジトリ内の両方に書き込みます。重要なのは、リポジトリ パターンが表すファサード、つまりメモリ内コレクションを維持することです。それは私にとって真の抽象化のようには感じられないので、私は別々のリポジトリを作成しません。その時点で、ボンネットの下のテクノロジーにデザインを指示させています。dddstepbystep.com から引用するには:

リポジトリの背後にあるもの あなたが好きなものはほとんど何でも。ええ、あなたはそれを正しく聞きました。データベースを作成することも、さまざまなデータベースを作成することもできます。リレーショナル データベースまたはオブジェクト データベースを使用できます。メモリ内データベース、またはメモリ内アイテムのリストを含むシングルトンを持つことができます。REST レイヤー、一連の SOA サービス、ファイル システム、またはインメモリ キャッシュを使用できます。ほとんど何でも使用できます。唯一の制限は、リポジトリがドメインに対するコレクションのように機能できる必要があることです。 . この柔軟性は、リポジトリと従来のデータ アクセス手法の主な違いです。

http://thinkddd.com/assets/2/Domain_Driven_Design_-_Step_by_Step.pdf

于 2011-02-08T22:59:51.963 に答える
1

まず、IoC コンテナーを使用していると仮定します。エンティティ タイプごとに真のリポジトリを作成することをお勧めします。これは、次のようなものを実装するクラスで各オブジェクト コンテキスト EntitySet をラップすることを意味します。

interface IRepository<TEntity> {
  TEntity Get(int id);
  void Add(TEntity entity);
  void Save(TEntity entity);
  void Remove(TEntity entity);
  bool CanPersist<T>(T entity);
}

CanPersist は、そのリポジトリ インスタンスが渡されたエンティティの永続化をサポートしているかどうかを返すだけであり、以下で説明する UnitOfWork.Save によって多態的に使用されます。

各 IRepository には、IRepository を「トランザクション」モードで構築できるようにするコンストラクタもあります。したがって、EF の場合は次のようになります。

public partial EFEntityARepository : IRepository<EntityA> {
  public EFEntityARepository(EFContext context, bool transactional) {
    _context = context;
    _transactional = transactional;
  }
  public void Add(EntityA entity) {
    _context.EntityAs.Add(entity);
    if (!_transactional) _context.SaveChanges();
  }
}

UnitOfWork は次のようになります。

interface UnitOfWork {
  void Add(TEntity entity);
  void Save(TEntity entity);
  void Remove(TEntity entity);
  void Complete();
}

UnitOfWork 実装は、依存性注入を使用してすべての IRepository のインスタンスを取得します。UnitOfWork.Save/Add/Remove では、UoW は引数エンティティを各 IRepository の CanPerist に渡します。戻り値の場合true、UnitOfWork は、その IRepository および目的の操作に固有のプライベート コレクションにそのエンティティを格納します。Complete では、UnitOfWork はすべてのプライベート エンティティ コレクションを調べ、各エンティティの適切な IRepository で適切な操作を呼び出します。

EF によって部分的に永続化され、AD によって部分的に永続化される必要があるエンティティがある場合、そのエンティティ タイプに対して 2 つの IRepository クラスが必要になります (両方とも、そのエンティティ タイプのインスタンスが渡されると、CanPersist から true を返します)。

EF と AD の間の原子性を維持することに関しては、それは別の重要な問題です。

于 2011-01-20T18:47:44.313 に答える
0

IMOこれらのリポジトリの両方への呼び出しをサービスタイプのクラスにラップします。次に、IoC / DIを使用して、リポジトリタイプをサービスクラスに挿入します。Ent用に1つ、合計2つのリポジトリがあります。フレームワークとADをサポートする1​​。このように、各リポジトリはその下にあるデータストアのみを処理し、クロスオーバーする必要はありません。

複数の作業タイプのユニットをサポートするために私が行ったことは、IUnitOfWorkをよりファクトリにすることです。実際の作業単位であり、commitメソッドしかないIUnitOfWorkScopeという別のタイプを作成します。

namespace Framework.Persistance.UnitOfWork
{
    public interface IUnitOfWork
    {
        IUnitOfWorkScope Get();

        IUnitOfWorkScope Get(bool shared);
    }

    public interface IUnitOfWorkScope : IDisposable
{
    void Commit();
}
}

これにより、作業単位のさまざまな実装をサービスに注入し、それらを並べて使用できるようになります。

于 2010-05-29T08:49:49.297 に答える