3

私はかなり長い間依存性注入を使用しており、この手法は本当に気に入っていますが、注入する必要がある依存性が多すぎるという問題がよくあります。

しかし、私はそれを簡単にする方法を見つけることができません。たとえば、メッセージを送信するいくつかのビジネス ロジックを含むクラスがあり、必要なことを行うために他の 2 つのビジネス ロジックの依存関係を受け入れます (1 つはデータを送信メッセージに変換し、もう 1 つは受信メッセージを変換します)。

ただし、これとは別に、 (内部にタイマーを作成する必要があるため)、ILogger(一意のキーを生成するため)などの「技術的な」依存関係が必要です。ITimerFactoryIKeyGenerator

そのため、リスト全体がかなり大きくなります。依存関係の数を減らすための良い一般的な方法はありますか?

4

1 に答える 1

4

それらを処理する 1 つの方法は、集約 (またはファサード) に向けてリファクタリングすることです。Mark Seemannはそれについて良い記事を書いています。したがって、次のものがあるとします(記事から抜粋):

public OrderProcessor(IOrderValidator validator,
                      IOrderShipper shipper,
                      IAccountsReceivable receivable,
                      IRateExchange exchange,
                      IUserContext userContext)

次のようにリファクタリングできます。

public OrderProcessor(IOrderValidator validator,
                      IOrderShipper shipper,
                      IOrderCollector collector)

ファサードはどこOrderCollectorにありますか (前の 3 つの依存関係をラップします):

public OrderCollector(IAccountsReceivable receivable,
                      IRateExchange exchange,
                      IUserContext userContext)

これが役立つことを願っています。

編集

分野横断的な問題 (たとえば、ロギングとキャッシング) とそれらを処理するための戦略に関して、ここに提案があります (これは私が通常行うことです)。

public interface IOrderService
{
    void DoAwesome();
}

public class OrderService : IOrderService
{
    public void DoAwesome()
    {
        // do your thing here ... no logging no nothing
    }
}

ここでは、decorator パターンを使用して、ロギングが有効になっている OrderService を作成します。

public class OrderServiceWithLogging : IOrderService
{
    private readonly IOrderService _orderService;
    private readonly ILogger _logger;

    public OrderServiceWithLogging(IOrderService orderService, ILogger logger)
    {
        _orderService = orderService;
        _logger = logger;
    }

    public void DoAwesome()
    {
        _orderService.DoAwesome();
        _logger.Log("Awesome is done!");
    }
}

少しオーバーヘッドがかかるように見えるかもしれませんが、私見ですが、クリーンでテスト可能です。

もう 1 つの方法は、アスペクト指向プログラミングに進み、基本的に特定のメソッド呼び出しをインターセプトし、結果としてタスクを実行するインターセプションなどの概念を調べることです。多くの DI フレームワーク (すべてと言いたいですか?) はインターセプトをサポートしているため、それはあなたが好むものかもしれません。

于 2013-08-13T08:29:08.750 に答える