CommandHandler和EventHandler命令

时间:2016-02-26 13:49:51

标签: design-patterns domain-driven-design cqrs command-pattern

我是关于CQRS的新手,想学习模式的工作顺序。我的命令处理程序和命令是这样的:

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

当我停止工作时,命令处理程序正在运行。

public class CreateWorkCommandhandler : ICommandHandler<CreateWork>
{
    public void Handle(CreateWork command)
    {
        Save to database...            
    }
}

我不会在控制器类中调用命令处理程序。我使用CommandExecuter按类型调用命令。

public class CommandExecuter
{

    public static void ExecuteCommand<TCommand>(TCommand command) where TCommand : ICommand
    {
        var handlerType = typeof(ICommandHandler<>).MakeGenericType(command.GetType());

        var handlers = serviceLocator.GetAll(handlerType);

        foreach (var handler in handlers)
            ((dynamic)handler).Handle((dynamic)command);
    }
}

我希望在创建工作后发送电子邮件并发送短信和其他内容。但由于分离的架构,我无法在Handle(CreateWork command)中执行这些步骤。

我认为这些步骤都是事件,这是真的吗?所以我需要eventevent handler类型。

public interface IEventHandler<in TEvent> where TEvent : IEvent
{
    void Handle(TEvent event);
}

我可以在哪里填充活动?在 CommandExecuter CommandHandler 中,我需要为事件提供多个事件。例如:

public class WorkCreated:IEvent {}

发送短信,发送电子邮件。

1 个答案:

答案 0 :(得分:4)

        foreach (var handler in handlers)
        ((dynamic)handler).Handle((dynamic)command);

看起来真的很奇怪。为什么在 / 上下文中,命令会有多个处理程序?

对于事件消息,该模式可能有意义;一个事件拥有零个或多个订阅者是正常的。但命令是发送给特定目标的消息,因此枚举许多处理程序似乎很奇怪。

关于你的问题

  

我希望在创建工作后发送电子邮件并发送短信和其他内容。但由于分离的体系结构,我无法在Handle(CreateWork命令)中执行这些步骤。

     

我认为这些步骤都是事件,这是真的吗?

事件是描述过去发生的事情的消息。这听起来像是一场比赛吗?在我看来,您正在描述一个命令 - 您希望某个系统为您发送电子邮件。这听起来不像是已经发生过的事情了吗?

EmailCommandSucceeded,SMSCommandFailed等等更精细的细节 - 那些是事件;过去发生的事情。

中,命令是更改域状态的提议(前提是域模型强制执行的业务不变量允许更改)。模型的响应通常分为两部分;提交事务(Repository.save())时要保留的数据,以及与世界其他地方共享的消息。这些消息可以是域事件,也可以是在其他事务/上下文中运行的命令。

因此,您的问题的通常答案是命令处理程序将命令关闭到域模型,并返回要调度的命令列表(在事务上下文之外)。

如果命令处理程序不能直接执行此操作,则可以选择发布EmailCommandScheduledEvent,然后让事件处理程序执行相同的工作。