Domain driven design CQRS+;按id对其他聚合根的DDD命令端查询
鉴于以下CQRS+DDD背景:Domain driven design CQRS+;按id对其他聚合根的DDD命令端查询,domain-driven-design,cqrs,Domain Driven Design,Cqrs,鉴于以下CQRS+DDD背景: 聚合根: 类消息{Guid Guid,字符串内容,Guid toUserGuid,MessageStatus status…} class用户{Guid、字符串名称、电子邮件…} 命令: CreateMessageCommand{Guid-messageGuid,字符串内容,Guid-toUserGuid…} 命令处理程序: CreateMessageCommandHandler=>创建消息聚合根目录(状态设置为“已接收请求”),并通过MessageRepo
聚合根:
类消息{Guid Guid,字符串内容,Guid toUserGuid,MessageStatus status…}
class用户{Guid、字符串名称、电子邮件…}
命令:
CreateMessageCommand{Guid-messageGuid,字符串内容,Guid-toUserGuid…}
命令处理程序:
CreateMessageCommandHandler
=>创建消息聚合根目录(状态设置为“已接收请求”),并通过MessageRepository
保存它(消息尚未发送。CreateMessageCommandHandler
仅创建和保存消息聚合根目录)。然后发布一条MessageCreatedEvent
事件:
MessageCreatedEvent{Guid messageGuid}
事件处理程序:
MessageCreatedEventHandler
=>使用event.messageGuid
通过MessageRepository
=>获取Message
?=><代码>emailService.Send(user.email,message.content)=>状态设置为“已发送”
我的问题是,在
MessageCreatedEventHandler
“?”部分,是否允许我通过message.toserguid
通过UserRepository
获取User.email
。另一个选项是域服务UserService
,方法GetEmailById(Guid userGuid)=>Email
,我认为它更好,因为事件处理程序不需要User
的整个对象,并且UserService
可以处理如何检索用户的所有逻辑(例如,使用UserRepository
)
我不想在这里获取读取模型(查询端),我只是需要来自聚合根的一些信息,而聚合根不是当前上下文
谢谢你,我感谢你对这个话题的评论和回答
TLDR:在CQRS命令处理程序/事件处理程序中,如何获取当前命令/事件上下文之外的聚合根的信息
TLDR:在CQRS命令处理程序/事件处理程序中,如何获取当前命令/事件上下文之外的聚合根的信息
通常的回答:您向某个商店索要所需信息的未锁定副本。该信息是,这意味着在您工作时权威副本可能正在更改(例如:您的用户在您尝试发送邮件时更改了他们的电子邮件地址)
机械地说,这通常看起来像是有一些“服务”接受标识符并返回您需要的信息(想想“存储库”,但没有更改数据的能力)
根据上下文,您可以从“应用程序代码”调用该服务,并将答案传递给“域代码”,或者您可以将服务本身传递给域代码(这是域服务模式)
在这两种情况下,让机器做正确的事情是相对简单的;选择主要是设计权衡(例如:从远程源复制数据可能会失败-是否希望将错误处理与域代码混合在一起?)感谢您提供的详细答案和文章!还有一个问题:考虑到我的业务逻辑允许系统向旧用户的电子邮件地址发送消息(即,在系统获取电子邮件地址和发送消息之间,用户更改了电子邮件地址),读取“外部数据”应该不在当前上下文的事务中是正确的吗?特别是您提供的文章中提到的没有跨服务边界的ACID事务
。只是想确保我的理解是正确的。或者换句话说,我可以说,只要没有ACID事务across服务边界,可以随意读取系统需要的命令/事件处理程序边界之外的数据,只是信息的副本可能会过时。