2

次の記事.NET Junkie - During the command side of my architectureを読みました。これは別の stackoverflow ユーザーによって提案されたもので、コマンド パターンの概要を説明し、記事の最後に DI でそれを使用する方法についての戦略を提供しています。

これは非常に役に立ちましたが、私が見逃していることが 1 つあります。たとえば、新しいクラスを作成するとしCheckoutCustomerCommandHandlerます。

MoveCustomerCommandHandlerさて、コンストラクターを介して何らかの理由でこのコマンドとをコントローラーに挿入する必要があるとしましょう。これは DI コンテナーのセットアップとコンストラクターにどのように影響しますか?

コアでは、どちらも同じインターフェースを実装しています。これにより、DI コンテナーのルックアップの問題が発生するようです。記事の例では、インジェクターのセットアップの例を次に示します。

public interface ICommandHandler<TCommand>
{
    void Handle(TCommand command);
}

// Exactly the same as before, but now with the interface.
public class MoveCustomerCommandHandler
: ICommandHandler<MoveCustomerCommand>
{
    private readonly UnitOfWork db;

    public MoveCustomerCommandHandler(UnitOfWork db,
    [Other dependencies here])
    {
        this.db = db;
    }

    public void Handle(MoveCustomerCommand command)
    {
        // TODO: Logic here
    }
}

// Again, same implementation as before, but now we depend
// upon the ICommandHandler abstraction.
public class CustomerController : Controller
{
    private ICommandHandler<MoveCustomerCommand> handler;

    public CustomerController(
    ICommandHandler<MoveCustomerCommand> handler)
    {
        this.handler = handler;
    }

    public void MoveCustomer(int customerId, 
        Address newAddress)
    {
        var command = new MoveCustomerCommand
        {
            CustomerId = customerId,
            NewAddress = newAddress
        };

        this.handler.Handle(command);
    }
}

using SimpleInjector;
using SimpleInjector.Extensions;

var container = new Container();

// Go look in all assemblies and register all implementations
// of ICommandHandler<T> by their closed interface:
container.RegisterManyForOpenGeneric(
    typeof(ICommandHandler<>),
    AppDomain.CurrentDomain.GetAssemblies());

// Decorate each returned ICommandHandler<T> object with
// a TransactionCommandHandlerDecorator<T>.
container.RegisterDecorator(typeof(ICommandHandler<>),
    typeof(TransactionCommandHandlerDecorator<>));

// Decorate each returned ICommandHandler<T> object with
// a DeadlockRetryCommandHandlerDecorator<T>.
container.RegisterDecorator(typeof(ICommandHandler<>),
    typeof(DeadlockRetryCommandHandlerDecorator<>));
4

1 に答える 1

2

クラス宣言は次のようになります...

public class CheckoutCustomerCommandHandler :
    ICommandHandler<CheckoutCustomerCommand> {...}

public class MoveCustomerCommandHandler : 
    ICommandHandler<MoveCustomerCommand> {...}

これらは同じインターフェイスを実装しているように見えますが、ジェネリック引数が異なるため、実際には 2 つの異なるインターフェイスにコンパイルされます。DI フレームワークはそれらを区別できます。

于 2012-11-01T19:11:23.520 に答える