首页 > 解决方案 > CQRS+DDD 命令端通过 id 查询其他聚合根

问题描述

给定以下 CQRS + DDD 背景:


聚合根:

class Message{Guid guid, string content, Guid toUserGuid, MessageStatus status...}

class User{Guid guid, string name, Email email...}


命令:

CreateMessageCommand{Guid messageGuid, string content, Guid toUserGuid...}


命令处理程序:

CreateMessageCommandHandler<CreateMessageCommand>=> 创建一个消息聚合根(状态设置为例如“Request Received”)并保存MessageRepository(消息尚未发送。CreateMessageCommandHandler仅创建并保存消息聚合根)。然后发布一个MessageCreatedEvent


事件:

MessageCreatedEvent{Guid messageGuid}


事件处理程序:

MessageCreatedEventHandler<MessageCreatedEvent>=>Message使用event.messageGuid通过MessageRepository=> ??? => emailService.Send(user.email, message.content)=> 状态设置为“已发送”


我的问题是,在MessageCreatedEventHandler<MessageCreatedEvent>“???” 部分,我是否可以通过User使用,例如获得。另一种选择是带有方法的域服务,我认为它更好,因为事件处理程序不需要整个对象,并且可以处理如何检索 a 的所有逻辑(例如 with )message.toUserGuidUserRepositoryuser.emailUserServiceGetEmailById(Guid userGuid) => EmailUserUserServiceUserUserRepository

我不是想在这里读取模型(查询端),我只需要来自聚合根的一些信息,这不是当前上下文。

谢谢,我感谢与此主题相关的任何评论和答案。

TLDR:在 CQRS 命令处理程序/事件处理程序中,我应该如何获取有关当前命令/事件上下文之外的聚合根的信息。

标签: domain-driven-designcqrs

解决方案


TLDR:在 CQRS 命令处理程序/事件处理程序中,我应该如何获取有关当前命令/事件上下文之外的聚合根的信息。

通常的答案是:您向某些商店索要所需信息的未锁定副本。该信息是外部数据,这意味着权威副本可能会在您工作时发生变化(例如:您的用户在您尝试发送消息时更改了他们的电子邮件地址)。

机械地,这通常看起来像有一些“服务”接受标识符并返回您需要的信息(想想“存储库”但没有更改数据的能力)。

根据上下文,您可以从“应用程序代码”调用该服务,并将答案传递给“域代码”,或者您可以将服务本身传递给域代码(这是域服务模式)。

无论哪种情况,让机器做正确的事情都是相对简单的;选择主要是设计权衡之一(例如:从远程源复制数据可能会失败 - 您是否希望将错误处理与您的域代码混合?)


推荐阅读