CQRS+DDD命令端查询其他聚合根的id
CQRS+DDD command side query for other aggregate root by 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>
=> 使用 event.messageGuid
通过 MessageRepository
获取 Message
=> ??? => emailService.Send(user.email, message.content)
=> 状态设置为“已发送”
我的问题是,在MessageCreatedEventHandler<MessageCreatedEvent>
“???”部分,我是否可以使用 message.toUserGuid
通过 UserRepository
获得 User
,例如得到 user.email
。另一种选择是使用方法 GetEmailById(Guid userGuid) => Email
的域服务 UserService
,我认为这更好,因为事件处理程序不需要 User
的整个对象,并且 UserService
可以处理如何检索 User
的所有逻辑(例如 UserRepository
)
我不想在这里获取读取模型(查询端),我只需要来自聚合根的一些信息,这不是当前上下文。
谢谢,非常感谢与此主题相关的任何评论和回答。
TLDR:在 CQRS 命令 handler/event 处理程序中,我应该如何获取有关当前 command/event 上下文之外的聚合根的信息。
TLDR: In CQRS command handler/event handler, how should I get information about aggregate root which is outside my current command/event context.
通常的回答:你向一些商店索取你需要的信息的解锁副本。该信息是 data on the outside,这意味着权威副本可能会在您工作时发生变化(例如:您的用户在您尝试发送消息时更改了他们的电子邮件地址)。
从机制上讲,这通常看起来像是有一些接受标识符和 returns 您需要的信息的“服务”(想想“存储库”,但没有更改数据的能力)。
根据上下文,您可以从您的“应用程序代码”调用该服务,并将答案传递给您的“领域代码”,或者您可以将服务本身传递给领域代码(这是领域服务模式).
在任何一种情况下,让机器做正确的事情都是相对直接的;选择主要是设计权衡之一(例如:从远程源复制数据可能会失败 - 您是否希望错误处理与您的域代码混合?)
鉴于以下 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>
=> 使用 event.messageGuid
通过 MessageRepository
获取 Message
=> ??? => emailService.Send(user.email, message.content)
=> 状态设置为“已发送”
我的问题是,在MessageCreatedEventHandler<MessageCreatedEvent>
“???”部分,我是否可以使用 message.toUserGuid
通过 UserRepository
获得 User
,例如得到 user.email
。另一种选择是使用方法 GetEmailById(Guid userGuid) => Email
的域服务 UserService
,我认为这更好,因为事件处理程序不需要 User
的整个对象,并且 UserService
可以处理如何检索 User
的所有逻辑(例如 UserRepository
)
我不想在这里获取读取模型(查询端),我只需要来自聚合根的一些信息,这不是当前上下文。
谢谢,非常感谢与此主题相关的任何评论和回答。
TLDR:在 CQRS 命令 handler/event 处理程序中,我应该如何获取有关当前 command/event 上下文之外的聚合根的信息。
TLDR: In CQRS command handler/event handler, how should I get information about aggregate root which is outside my current command/event context.
通常的回答:你向一些商店索取你需要的信息的解锁副本。该信息是 data on the outside,这意味着权威副本可能会在您工作时发生变化(例如:您的用户在您尝试发送消息时更改了他们的电子邮件地址)。
从机制上讲,这通常看起来像是有一些接受标识符和 returns 您需要的信息的“服务”(想想“存储库”,但没有更改数据的能力)。
根据上下文,您可以从您的“应用程序代码”调用该服务,并将答案传递给您的“领域代码”,或者您可以将服务本身传递给领域代码(这是领域服务模式).
在任何一种情况下,让机器做正确的事情都是相对直接的;选择主要是设计权衡之一(例如:从远程源复制数据可能会失败 - 您是否希望错误处理与您的域代码混合?)