Сконфигурируйте декораторы для универсальных интерфейсов и внедрите все экземпляры в конструктор с не универсальным аргументом интерфейса в Simple Injector

Я использовал шаблон, очень похожий на то, что описанов этой отличной статье иметь команды и запросы в качестве объектов. Я также использую SimpleInjector в качестве DI-контейнера.

Единственное существенное отличие состоит в том, что скорее контроллер принимает явную зависимость от некоторыхICommandHandler<TCommand> Я хочу, чтобы контроллеры взяли зависимость от объекта (Dispatcher) который возьметICommand экземпляр и разрешить правильный обработчик для этой команды. Это уменьшит количество параметров, которые должны принимать конструкторы, и сделает все это немного проще в использовании.

Так что мойDispatcher Конструктор объектов выглядит так:

public CommandAndQueryDispatcher(IEnumerable<ICommandHandler> commandHandlers,
    IEnumerable<IQueryHandler> queryHandlers)
{
}

и мои интерфейсы CommandHandler выглядят так:

public interface ICommandHandler<in TCommand> : ICommandHandler 
    where TCommand : ICommand
{
    void Execute(TCommand command, ICommandAndQueryDispatcher dispatcher);
}

public interface ICommandHandler
{
    void Execute(object command, ICommandAndQueryDispatcher dispatcher);
}

И типичный обработчик команд выглядит так:

public abstract class CommandHandlerBase<TCommand> : ICommandHandler<TCommand> 
    where TCommand : ICommand
{
    public abstract void Execute(TCommand command, ICommandAndQueryDispatcher dispatcher);

    public void Execute(object command, ICommandAndQueryDispatcher dispatcher)
    {
        Execute((TCommand) command, dispatcher);
    }
}

internal class DeleteTeamCommandHandler : CommandHandlerBase<DeleteTeamCommand>
{
    public DeleteTeamCommandHandler(){        }

    public override void Execute(DeleteTeamCommand command, 
        ICommandAndQueryDispatcher dispatcher)
    {
       ... functionality here...
    }
}

Однако это изменение вызвало некоторые проблемы, и теперь я хочу добавить некоторые декораторы к моим командам и запросам, у меня возникли некоторые проблемы.

Чтобы все команды и запросы были введены вDispatcher Я сделал их все имеют базовый, универсальный интерфейсICommandHandler а такжеIQueryHandlerзатем опросите фактически полученные экземпляры (которые являются общими), чтобы получить тип команды, которую они обрабатывают, чтобы зарегистрировать их, чтобы я мог позже найти обработчик на основе типа данной команды.

Теперь, когда я пытаюсь использовать декораторы, как указано в примерах, мне кажется, что я ничего не могу вставить в мойDispatcher, поскольку оформленные экземпляры зарегистрированы как универсальные типы, так что не разрешаются как базовыеICommandHandler экземпляров. Если я попытаюсь сделать декораторы не универсальными, тогда внедряемые экземпляры не будут иметь параметров универсального типа, поэтому я не могу найти, для какого типа команды это обработчик.

Я чувствую, что, должно быть, мне не хватает чего-то довольно простого.

Так что мой вопрос либо

Как я могу получить все экземпляры открытого универсального типа из приведения контейнера в качестве базового интерфейса, переданного в мойDispatcher?

ИЛИ ЖЕ

Есть ли лучший способ для меня реализовать функциональность диспетчера, чтобы мои контроллеры могли не знать, какой обработчик будет обрабатывать команду / запрос, который лучше работает с SimpleInjector?

Ответы на вопрос(1)

Ваш ответ на вопрос