我正在处理带有域事件的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; }
}
我只想知道命令是成功还是失败,以及如果失败,为什么。我最终得到了这种递归树结构。我使这个问题变得过于复杂了吗?
答案 0 :(得分:0)
其中一个命令失败时会发生什么
因此,在域事件的通常情况下,答案是整个事务失败。
我只想知道命令是成功还是失败,如果失败,为什么。
该信息如何返回给调用者取决于您的代码样式-您可以引发异常,或者返回某种Either
数据类型,或者通知回调处理程序,或者...
如果呼叫者处于另一个进程中,则需要将内部选项转换为某种消息。成功/失败状态以及可选的“原因”字段将为您提供足够的经验,以弄清楚您要在下一发行版的架构中包含什么。