3

UnitOfWork を実装して、すべてのリポジトリへの参照を保持できるようにしました。

public interface IUnitOfWork
{
   void Commit();
   void RollBack();
}

public interface IMyUnitOfWork : IUnitOfWork
{
   IFooRepository Foos { get; }
   IBarRepository Bars { get; }
   // Other repositories ...
}

リポジトリは、一般的なタイプのリポジトリ インターフェイスを実装することに注意してください。

public interface IFooRepository : IRepository<Entities.Foo>
{
    // FooRepository specific methods goes here.
}

public interface IRepository<T> : IRepository
    where T : class
{
}

これらのリポジトリを UnitOfWork に挿入するにはどうすればよいですか。もちろん、遅延読み込み動作が必要です。例えば:

public class ConcreteUnitOfWork : IMyUnitOfWork
{
   private readonly IUnityContainer unityContainer;
   private IFooRepository fooRepository;

   public ConcreteUnitOfWork(IUnityContainer unityContainer)
   {
      this.repositoryFactory = repositoryFactory;
   }

   public IFooRepository Foos
   {
      get 
      { 
         return this.fooRepository ?? 
            (this.fooRepository = unityContainer.Resolve<IFooRepository>()); 
      }
   }
}

Unity コンテナを UnitOfWork に渡すのが間違っていることは知っていますが、この問題を解決するためにどのパターンを提供しますか?

リポジトリ参照を UnitOfWork に保持するべきではないと言うかもしれませんが、いくつかのリポジトリを必要とするサービス クラスを想定してください。この設計では、UnitOfWork をコンストラクター パラメーター (コンストラクター インジェクション) としてサービス クラスに渡すことができますが、リポジトリ参照を UnitOfWork に保持しないと、必要なすべてのリポジトリーをコンストラクター パラメーターとして渡す必要があり、何を知っているかがわかります。につながります。

- アップデート -

私が完全に間違っている場合はお知らせください。UnitOfWork でリポジトリを構成するべきではありません。では、ここで「コンストラクターのオーバーインジェクション」についての解決策を教えてください。

-- UPDATE2 --

新しいリポジトリを追加する (新しいプロパティを追加する) ときに UnitOfWork クラスを変更する必要があるため、UnitOfWork からリポジトリを作成 (参照) すると、Open/Closed の原則が破られるようです。

それが正しければ、リファクタリングを検討する必要があります。アイデアを教えてください。

4

1 に答える 1

5

現在の設計案では、複数の責任が IMyUnitOfWork インターフェイスに組み込まれているようです。そうしないと、サービスクラスが各リポジトリを個別に取得する必要がある可能性があるためだとおっしゃっています。次のような意味だと思います。

public MyService(
   IUnitOfWork uow,
   IFooRepository fooRepository,
   IBarRepository barRepository)

これは、はるかにシンプルでクリーンなデザインのように思えます。

しかし、コンストラクターの過剰注入はどうでしょうか?

まあ、それはあります...しかし、問題は、これが ConcreteUnitOfWork 実装で現在抱えている問題とまったく同じであるということです。コンストラクターの過剰注入の臭いをまったく解決していません。別のクラスに移動しただけです。

実際、これを ConcreteUnitOfWork に移動することで、状況への対処がより困難になりました。ConcreteUnitOfWork は純粋なインフラストラクチャ クラス (場合によってはサポート クラス) であるため、ビジネス コンテキストを持たないため、ここでコンストラクターの過剰注入の臭いを解決する方法を提案するのは非常に困難です。

一方、特定のサービス (ま​​たはおそらくコントローラー) は、より専門化され、ビジネス コンテキストの知識を持っている傾向があるため、ジョブを実行するためにすべてのリポジトリは必要ありません。やりすぎようとする。

このような特定のビジネス コンポーネントは、Facade Service にリファクタリングする方が適切です。

于 2012-08-03T16:19:26.367 に答える