CommonDomain 中的存储库仅公开“GetById()”。那么,如果我的处理程序需要一个客户列表,例如,该怎么办?
4 回答
从表面上看,如果您需要对多个聚合执行操作,您只需在命令中提供每个聚合的 ID(客户端将从查询端获取),然后从存储库中获取每个聚合。
但是,查看您对另一个答案的评论之一,我发现您实际上指的是基于设置的验证。
这个问题引起了很多关于如何做到这一点的争论,Greg Young 写了一篇关于它的博客文章。
经典问题是“如何在处理我的“CreateUserCommand”时检查用户名是否未被使用。我相信建议的方法是假设客户端已经通过在发出命令之前询问查询方来完成此检查。创建用户聚合时,UserCreatedEvent 将由查询端引发和处理。在这里,插入查询将失败(由于数据库中的检查或唯一约束),并且将发出补偿命令,该命令将删除新创建的聚合,并可能通过电子邮件通知用户用户名已被占用。
要点是,您假设客户端已完成检查。我知道这种方法一开始很难掌握——但这是最终一致性的本质。
此外,您可能想阅读另一个类似的问题,其中包含来自Udi Dahan的一些明智的话。
在经典的事件溯源模型中,获取所有客户等查询将由单独的查询处理程序执行,该处理程序侦听域中的所有事件并构建查询模型以满足相关问题。
例如,如果您需要按姓氏查询客户,您可以监听所有客户创建和客户姓名更改事件,只需将一个姓氏表更新为客户 ID 对。您可以保存与显示数据的 UI 相关的其他信息,或者您可以简单地保存 ID 并转到相关客户的存储库,以便进一步与他们合作。
您不需要处理程序中的客户列表。每个聚合必须在其自己的事务中处理。如果您想向用户显示此列表 - 只需构建适当的视图。
您的命令需要包含它应该操作的聚合根的 id。发送命令的客户端将使用您的 readmodel 中的视图查找此 ID。此视图将填充来自您的 AR 发出的事件的数据。