5

サービス層にServiceAとの 2 つのサービスがありServiceB、それぞれにインターフェイス (IServiceAIServiceBそれぞれ) があるとします。

UI レイヤーは、メソッドからDTOを返すサービス インターフェイスへの参照のみを持ちます。具体的なサービス クラスは、ドメイン モデル (EF POCO) を DTO にマッピングする役割を果たします。

ServiceAそのサービスでいくつかのメソッドを呼び出すために、IoC コンテナーを使用しIServiceBて依存性注入を介して依存関係を取得します。

これを行う際に発生する問題がいくつかあります。

  1. メソッドを呼び出したり、結果を消費したりするためだけに、DTO との間で不要または重複するマッピング。

  2. 呼び出し元のメソッドを、呼び出されたメソッドの入力パラメーターと戻り値の型の DTO コントラクトに緊密に結合します。

最初は、ロジックを内部メソッドにリファクタリングし、それを両方のサービスから呼び出すことを考えていました。ただしServiceA、インターフェイスに依存するためIServiceB、内部メソッドは公開されません。

この問題にどのように対処しますか?

詳細情報(リクエストに応じてサンプルコードを追加):

// This is the domain model
public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
}

// This is a dto for the domain model
public class CustomerDto
{
    public string Name { get; set; }
}

// Interface for ServiceA
public interface IServiceA
{
    void AddCustomer();
}

// ServiceA
public class ServiceA : IServiceA
{
    private readonly IServiceB _serviceB;

    // ServiceA takes in an IServiceB as a dependency
    public ServiceA(IServiceB serviceB)
    {
        _serviceB = serviceB;
    }

    public void AddCustomer()
    {
        var entity = new Customer();

        // !! This is the key part !!

        // I have to map to a dto in order to call the method on ServiceB.
        // This is a VERY simple example but this unnecessary mapping 
        // keeps cropping up throughout the service layer whenever
        // I want to make calls between services.

        var dto = Mapper.CreateFrom<CustomerDto>(entity);

        _serviceB.DoSomethingElseWithACustomer(dto);
    }
}

// Interface for ServiceB
public interface IServiceB
{
    void DoSomethingElseWithACustomer(CustomerDto customer);
}

// ServiceB
public class ServiceB : IServiceB
{
    public void DoSomethingElseWithACustomer(CustomerDto customer)
    {
        // Some logic here
    }
}
4

3 に答える 3

2

DTO への不必要なマッピングについて:データベースへのアクセスにドメイン駆動設計を使用する場合は、データ アクセス オブジェクトまたはリポジトリの使用を検討してください。したがって、マップされた (エンティティ) オブジェクトを直接操作するサービス レイヤーの下に、一種の「ユーティリティ レイヤー」を配置できます。

カップリングの種類について:ServiceB複数のインターフェイス、特にサーバー側でのみ表示されるインターフェイスを実装できます。ServiceAそのインターフェイスに依存してServiceB、クライアント側への公開に適していないより多くの内部部分にアクセスできます。

于 2013-07-31T12:59:46.313 に答える