Example: Business rules states that the customer should get a confirmation message (email or similar) when an order has been placed.
假设NewOrderRegisteredEvent是从域中发出的,并由发送确认消息的事件监听器拾取.当这样做时,一些其他事件处理程序会抛出异常或其他问题,并且工作单元回滚.我们现在已经向用户发送了一个确认消息,回馈了一些内容.
解决问题的“cqrs”方式是什么,你想在一个工作单位后做些什么?另一个复杂因素是重播事件.当我重播录制的事件以构建新的视图/投影时,我不希望重新发送旧的确认消息.
我最好的理论到目前为止:我刚刚开始研究cqrs的迷人世界,并想知道这是否会被实现为一个传奇?如果一个传奇像一个状态机,每个过渡只能发生一次,那么我猜想会解决这个问题?我只是很难看到如何与命令总线和域事件配合在一起.
解决方法
>除非命令成功执行,否则不希望发送邮件.
首先,为什么命令处理程序(如另一个答案中提出的)将是错误的地方:在某些情况下,命令处理程序将无法判断命令是否会最终成功.命令处理程序调用邮件发送也会将处理知识放在命令处理程序中,这将破坏SRM并将业务规则与应用程序层紧密耦合.
邮件应该在事后发送,即从事件处理程序发送.
为了防止这个处理程序在播放过程中触发,你可以不注册它.这与您测试应用程序的方式类似.你只注册你实际需要的处理程序.
>生产系统 – >注册所有事件处理程序
>测试 – >只注册测试的事件处理程序
> Replay – >仅注册投影/非归一化处理程序
另一个 – 更松散的耦合,虽然有点复杂 – 可能会有一个Saga处理NewOrderRegisteredEvent并发出一个SendMail命令到适当的有限的上下文(谢谢,Yves Reynhout,指出这个问题的意见).