我是否使这个复杂化了? (CQRS,域事件和命令失败)

时间:2018-08-06 18:53:23

标签: c# cqrs domain-events

我正在处理带有域事件的CQRS框架,并且遇到了一些我想提出建议的代码味道。

我没有使用事件源(ES)。 ES事件与域事件不同。域事件对域而言很有趣,并且可能导致发出新命令。 ES事件对于持久性存储很有趣。 ES事件也可以是域事件,但并非所有ES事件都是域事件。

我的问题的根源在于以下陈述:

  

域事件...可能会导致新命令...

具体来说,当其中一个 命令失败时会发生什么。

在我阅读的CQRS文章中,他们说应用程序层负责在将命令发送到命令总线之前对其进行验证。 我不同意这有两个原因。 1)我不信任客户端(安全欺骗)。 2)随着应用程序的成熟和新事件/处理程序/命令的添加,命令A的验证可能不知道它也需要验证Command Foo。

因此,应用程序层需要知道命令是否成功。如果失败,则应用程序层需要一些信息来解释原因。但是使用触发事件的命令发出发出触发事件的新命令……我最终得到的响应类如下:

public interface ICommandResponse
{
    ICommand OriginatingCommand { get; set; }
    bool Successful { get; set; }
    IEnumerable<Exception> Exceptions { get; set; }
    IEnumerable<ICommandResponse> DerivativeCommands { get; set; }
    IEnumerable<IEventResponse> EventResponses { get; set; }
}

public interface IEventResponse
{
    IEvent OriginatingEvent { get; set; }
    bool Successful { get; set; }
    IEnumerable<Exception> Exceptions { get; set; }
    IEnumerable<IEventHandlerResponse> EventHandlerResponses { get; set; }
}

public interface IEventHandlerResponse
{
    string Descriptor { get; set; } // TODO: A way to identify the event handler.
    bool Successful { get; set; }
    IEnumerable<Exception> Exceptions { get; set; }
    IEnumerable<ICommandResponse> DerivativeCommands { get; set; }
}

我只想知道命令是成功还是失败,以及如果失败,为什么。我最终得到了这种递归树结构。我使这个问题变得过于复杂了吗?

1 个答案:

答案 0 :(得分:0)

  

其中一个命令失败时会发生什么

因此,在域事件的通常情况下,答案是整个事务失败。

  

我只想知道命令是成功还是失败,如果失败,为什么。

该信息如何返回给调用者取决于您的代码样式-您可以引发异常,或者返回某种Either数据类型,或者通知回调处理程序,或者...

如果呼叫者处于另一个进程中,则需要将内部选项转换为某种消息。成功/失败状态以及可选的“原因”字段将为您提供足够的经验,以弄清楚您要在下一发行版的架构中包含什么。