同様の質問が何度か議論されていることは知っていますが、私の問題は少し異なると思います。データ アクセス用のリポジトリ パターンと Entity Framework インフラストラクチャを使用して、ドメイン駆動設計に基づくアプリケーション アーキテクチャを試しています。
私が達成しようとしているのは、ユニットオブワークも認識できるユニットテスト可能なシステムを持つことです。
私は、アプリケーション内のすべてのビジネス ロジックを処理するコア サービスがシステム内にある設計が好きです。つまり、ICustomerRepository.Find(int id) の代わりに、ある種の CustomerService.AddOrder(int customerId, Order order) があります。 Orders.Add(注文順)。このアプローチを使用すると、より簡単で直感的なインターフェイスを使用できます。
(もちろん、CustomerService は ICustomerRepository に依存しており、おそらく IOrderRepository にも依存していますが、ロジック自体は処理されます)。
しかし!このアプローチでは、作業単位の問題が発生します。
コア サービス内に制御可能な作業単位が必要です。つまり、新しい作業単位を開始し、ジョブを実行し、それを破棄できるようにする必要があります。
私が思いついたこれを行う1つの方法は次のとおりです。
public interface IUnitOfWork
{
ICustomerRepository CustomerRepository { get; set; }
IOrderRepository OrderRepository { get; set; }
}
public interface IUnitOfWorkFactory
{
void New(Action<IUnitOfWork> work); // this will let you create and then dispose a new instance of IUnitOfWork implementation
}
public class CustomerService
{
privateTUowFactory _uow { get; private set; }
public CustomerService(IUnitOfWorkFactory uowFactory)
{
_uow = uowFactory;
}
public void AddNewOrder(int id, string newName)
{
_uow.New(work =>
{
var customer = work.CustomerRepository.Find(id);
// Do some other required stuff
work.Commit();
});
}
}
その後、IUnitOfWorkFactory、IUnitOfWork、およびリポジトリの実装を作成するだけです。クライアント コードでは、CustomerService に依存するだけでよく、IOC コンテナーによって簡単に処理されます。
私はこのアプローチが好きです。なぜなら、それはちょっとコンパクトで、よく構造化され、論理的に整理されていて、直感的だからです。統合テストは簡単ですが、現時点では私の関心事ではありません。
どんなアイデアでも大歓迎です。
どうもありがとう!