шаблон команды с использованием внедрения зависимостей для контроллера MVC 3

Я прочитал следующую статью .NET Junkie - Между тем ... на стороне команд моей архитектуры, предложенной другим пользователем stackoverflow, который описывает шаблон команды и предоставляет стратегию использования его с DI в конце статьи.

Это очень помогло, но единственное, чего мне не хватает, - скажем, я создаю новый класс с именем 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<>));

person user1790300    schedule 01.11.2012    source источник
comment
Похоже, это вопрос, относящийся к SimpleInjector. Я могу сказать вам, что другие контейнеры DI, такие как Ninject и Autofac, поддерживают этот сценарий.   -  person neontapir    schedule 01.11.2012


Ответы (1)


Вот как будут выглядеть объявления вашего класса ...

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

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

Может показаться, что они реализуют один и тот же интерфейс, но на самом деле они компилируются в два разных интерфейса, потому что аргументы универсальных типов различны. Ваша структура DI сможет различать их.

person TylerOhlsen    schedule 01.11.2012
comment
Спасибо. Я боялся, что это создаст огромную проблему. Вы знаете, будет ли это работать с блоком приложения Unity? - person user1790300; 01.11.2012
comment
У Unity не будет проблем с решением вашей реализации закрытого универсального типа. Проблема, с которой вы, вероятно, столкнетесь, заключается в том, как зарегистрировать декораторы, поскольку нет эквивалента RegisterDecorator. Эта статья о Unity Interception Extension может оказаться полезным на этом этапе. - person TylerOhlsen; 02.11.2012
comment
Спасибо. Проверяю статью сейчас. - person user1790300; 02.11.2012
comment
Для протокола, я использовал декораторы SimpleInjector, и они отлично работают. - person Facio Ratio; 14.11.2012