4

我必须设计一个 Command/CommandHandler 模块,并且正在为设计的细节而苦苦挣扎。

我创建了一个(空)接口:

public interface ICommand {}

这是由各种命令实现的,

例如

public interface TestCommand : ICommand {}

一个(或多个)CommandHandler 可以注册ICommand. 为了避免不断转换,我构建了一个接口:

public interface ICommandHandler<in TCommand>
       where TCommand : ICommand
{
    void Handle(TCommand command);
}

到目前为止一切都很好......命令调度系统是令人不安的东西:命令处理程序应该由 Autofac(或任何其他 DI 系统)注入,例如:

public CommandDispatcher (IEnumerable<ICommandHandler<ICommand>> commandHandlers)

如您所见,这是不可能的。ICommandHandler<CommandType1>并且ICommandHandler<CommandType2>不是派生自ICommandHandler<ICommand>,因此不能放入同一个 IEnumerable。

有什么建议如何以一种没有问题的方式设计它吗?

4

1 回答 1

3

通常,您会在调用它们之前解决它们。例如,在 Autofac

class CommandDispatcher
{
    private readonly Autofac.IComponentContext context; // inject this

    public void Dispatch<TCommand>(TCommand command)
    {
        var handlers = context.Resolve<IEnumerable<ICommandHandler<TCommand>>>();
        foreach (var handler in handlers)
        {
            handler.Handle(command);
        }
    }

    public void ReflectionDispatch(ICommand command)
    {
        Action<CommandDispatcher, ICommand> action = BuildAction(command.GetType());
        // see link below for an idea of how to implement BuildAction

        action(this, command);
    }
}

如果您需要将方法签名更改为Dispatch(ICommand command),请参阅此答案。您应该能够根据自己的情况进行调整。

于 2013-05-29T17:55:57.540 回答