1

同様の質問が何度か議論されていることは知っていますが、私の問題は少し異なると思います。データ アクセス用のリポジトリ パターンと 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 コンテナーによって簡単に処理されます。

私はこのアプローチが好きです。なぜなら、それはちょっとコンパクトで、よく構造化され、論理的に整理されていて、直感的だからです。統合テストは簡単ですが、現時点では私の関心事ではありません。

どんなアイデアでも大歓迎です。

どうもありがとう!

4

2 に答える 2

2

今説明したのは、ドメイン サービスの形式です。私は自分のドメイン コードを UoW に公開しない傾向にありますが、個人的な好みであることは確かです。ドメイン サービスに UoW スコープを制御させることで、ドメイン サービスに本来あるべきではない責任が与えられます (その時点では、それはアプリケーション サービスです)。代わりに、ドメイン サービスが連携する必要があるリポジトリ (およびオプションで他のサービス) に依存するようにします (十分に明確にしますが、混乱を招くことはありません)。テスト可能/プラグ可能にする目的でインターフェースを導入しているようですが、現時点ではそれらから多くを得ていません。インメモリ dbcontext (EF) に依存しないほうがよいのではないでしょうか? そのためのナゲットパッケージがあると思います。そうすれば、インメモリ dbcontext をリポジトリに注入できます (私はあなたが d これらの) 実装を維持したい。SUT ファクトリ (テスト対象のシステムを作成するもの、つまりこの場合はドメイン サービスを作成するもの) はすべてを結び付け、インメモリ dbcontext を使用して制御およびアサートできるようにします。または、独自のインメモリ リポジトリを作成するか、モッキングを使用することもできます (ただし、それはもろく、苦痛の世界になるでしょう)。最初のいくつかのテストを作成するときは、冗長性に注意を払い、執拗にリファクタリングしてください。そうしないと、これらのテストを書くのが面倒になったり、長期にわたって維持するのが負担になったりします。または、独自のインメモリ リポジトリを作成するか、モッキングを使用することもできます (ただし、それはもろく、苦痛の世界になるでしょう)。最初のいくつかのテストを作成するときは、冗長性に注意を払い、執拗にリファクタリングしてください。そうしないと、これらのテストを書くのが面倒になったり、長期にわたって維持するのが負担になったりします。または、独自のインメモリ リポジトリを作成するか、モッキングを使用することもできます (ただし、それはもろく、苦痛の世界になるでしょう)。最初のいくつかのテストを作成するときは、冗長性に注意を払い、執拗にリファクタリングしてください。そうしないと、これらのテストを書くのが面倒になったり、長期にわたって維持するのが負担になったりします。

于 2013-05-11T13:27:09.650 に答える