Сконфигурируйте декораторы для универсальных интерфейсов и внедрите все экземпляры в конструктор с не универсальным аргументом интерфейса в 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?