【问题标题】:CommandHandler and EventHandler orderCommandHandler 和 EventHandler 顺序
【发布时间】:2016-06-09 18:29:42
【问题描述】:

我是 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);
}

我可以在哪里填充事件?在 CommandExecuterCommandHandler 我需要多个事件来处理一个事件。例如:

公共类 WorkCreated:IEvent{}

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

【问题讨论】:

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


    【解决方案1】:
            foreach (var handler in handlers)
            ((dynamic)handler).Handle((dynamic)command);
    

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

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

    关于你的问题

    我想在工作创建后发送电子邮件和发送短信和其他事情。但由于架构分离,我无法在 Handle(CreateWork 命令) 中执行这些步骤。

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

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

    EmailCommandSucceeded、SMSCommandFailed 等更详细的信息 -- 那些 是事件;过去发生的事情。

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

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

    如果命令处理程序不能直接执行此操作,另一种方法可能是发布一个 EmailCommandScheduledEvent,然后让事件处理程序执行相同的工作。

    【讨论】:

    • 我同意 foreach 不适合处理程序。最好执行 handlers.single() 以确保该命令只有一个处理程序。
    猜你喜欢
    • 1970-01-01
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 2014-08-19
    • 1970-01-01
    • 2021-10-22
    • 2018-02-24
    相关资源
    最近更新 更多