【发布时间】:2011-01-02 04:40:08
【问题描述】:
我们正在试用CQRS。我们有一个验证情况,客户服务(域服务)需要知道客户是否存在。客户的电子邮件地址是独一无二的。我们的客户存储库(通用存储库)只有 Get(id) 和 Add(customer)。 CustomerService 应该如何确定 Customer 是否存在?
【问题讨论】:
我们正在试用CQRS。我们有一个验证情况,客户服务(域服务)需要知道客户是否存在。客户的电子邮件地址是独一无二的。我们的客户存储库(通用存储库)只有 Get(id) 和 Add(customer)。 CustomerService 应该如何确定 Customer 是否存在?
【问题讨论】:
看看这篇博文:Set based validation in the CQRS Architecture。
它解决了这个问题。这是在 CQRS 中处理的复杂问题。 Bjarte 的建议是查询报告数据库中现有的客户电子邮件地址,并在找到电子邮件地址时向域模型发出补偿命令(例如CustomerEmailAddressIsNotUniqueCompensatingCommand)。然后,您可以触发适当的事件,其中可能包括 UndoCustomerCreationEvent。
通读上述博客文章中的 cmets 以获得替代想法。
Adam D. 在评论中建议验证是一个域问题。因此,您可以将 ReservedEmailAddresses 存储在有助于创建客户并由事件存储中的事件补充的服务中。
我不确定这个问题是否有一个简单的解决方案,感觉完全干净。让我知道你的想法!
祝你好运!
【讨论】:
CreateNewUserCommand,最终为同一用户聚合了 100 多个用户。这确实是一个巨大的故障点,似乎没有人知道如何正确解决。 (我也不知道,否则 Google 不会把我带到这里 :p)
这个问题不必那么复杂:
将数据库用于它的优点,不要被 ORM 限制所困扰。
【讨论】:
Udi Dahan http://www.udidahan.com/2009/12/09/clarified-cqrs/ 的这篇帖子包含以下段落:
“此外,我们不应该需要访问查询存储来处理命令——任何需要的状态都应该由自治组件管理——这是自治含义的一部分。”
我相信 Udi 建议简单地向数据库添加一个唯一约束。
但是,如果您不想这样做,根据上面的陈述,我建议您将“ByEmail”方法添加到存储库并完成它 - 但是 Udi 可能会有更好的建议。 .
【讨论】:
希望我还不算太晚...但是我们在项目中遇到了类似的情况,我们实际上拦截了命令执行程序并将其附加到为该命令创建的规则集,然后使用查询来获取数据。
所以在这种情况下,我们可以有一个名为 CustomerEmailMustBeUniqueRule 的类,当 RegisterCustomerCommandExecutor 将要执行命令“RegisterCustomerCommand”时,它由 RuleEngine 获取。该规则类负责查询数据库以查找电子邮件 ID 是否存在并通过引发无效标志来停止执行...
【讨论】: