1

我正在开发一个带有域事件的 CQRS 框架,我遇到了一种代码味道,我想得到一些建议。

我没有使用事件溯源(ES)。ES 事件与领域事件不同。域事件是域感兴趣的并且可能导致发出新命令。ES 事件对持久存储很感兴趣。一个 ES 事件也可能是一个领域事件,但并不是所有的 ES 事件都是领域事件。

我的问题的根源在于声明:

域事件……可能会导致新命令……</p>

具体来说,当这些命令之一失败时会发生什么。

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

我想要的只是能够判断一个命令是成功还是失败,如果它失败了,为什么。我最终得到了这个递归树结构。我是否过于复杂了?

4

1 回答 1

0

当这些命令之一失败时会发生什么

因此,在域事件的通常上下文中,答案是整个事务都失败了。

我想要的只是能够判断一个命令是成功还是失败,如果它失败了,为什么。

这些信息如何返回给调用者取决于你的代码风格——你可以抛出异常,或者返回某种Either数据类型,或者通知回调处理程序,或者......

如果调用者在另一个进程中,您将需要将内部选项转换为某种消息。带有可选原因字段的成功/失败状态将使您有足够的经验来确定您希望在下一个版本的架构中包含什么。

于 2018-08-06T19:15:17.430 回答