我正在迈出在新项目中实施CQRS的第一步。 遵循CQRS方法,我使用MediatR作为协调命令的框架。
我还使用FluentValidation和ValidationBehavior来实现命令验证。但是我正在努力定义将哪种验证放在哪里:
我想了解将验证放在哪里:
由于我目前已实现,所以我无法在 aggregate 根目录中访问 IRepository 实现。是由DI注入此存储库的命令处理程序,它们在聚合根上执行操作,但也负责调用例如保存或添加以最终更新数据库。
答案 0 :(得分:0)
在“理想的” CQRS中,您的聚合状态应包含执行命令所需的所有内容,并且您不应在命令执行期间与其他聚合对话(因为它们超出了一致性范围)
因此,业务规则验证(是否可以执行给定命令的决定)应转到聚合的命令处理程序中。
在发送命令之前-在客户端上,以及在将命令传递给命令处理程序之前(由于我们无法完全信任客户端),应检查命令格式设置规则(必填字段,允许的值)。
因此,我将命令格式验证规则保持在更接近命令定义的位置-可能是以声明性形式出现,而不是作为专用验证器。
在某些情况下,如果不查询其他聚合的状态,聚合将无法完全检查命令的正确性。这是good article about inter-aggregate communication。简而言之-在执行命令期间,您不应该与其他聚合对话。
经典示例是使用唯一名称创建用户。社区的共识似乎是:
您在发送命令之前验证用户名在客户端中是否唯一。
用户聚合在不检查唯一性的情况下执行命令。
在少数情况下,有人在您发送命令之前注册了相同的用户名,这会被投影代码捕获,并导致手动解决的异常。还是有些传奇人物会监视重复的用户名并以某种方式处理此问题。
因此-需要更好地进行集合间通信的业务规则验证应放在Saga / Process Manager中