假设我有一个基于CQRS事件源基础的应用程序:
我的问题是:在步骤1和3中,我们是否需要在Command和Event DTO中提供所有信息,还是可以传递处理程序可以从数据库中提取的某些实体的ID?
示例:
Employee Aggregate具有名字,姓氏,电子邮件以及一些VO,例如地址,电话等。
它是工作人员实体的根,所以在我的应用程序中,我有一个员工聚合ID(UUID,生成域)和工作人员实体ID(整数,数据库生成)的映射
命令端:
在RegisterEmployee命令上,我是否需要传递所有需要充填所有Employee字段的数据?
然后我将拥有一个很大的构造函数,其中包含名字,姓氏,电子邮件,地址,电话1,电话2等。
我不能仅在命令中提供基本字段(名字,姓氏,电子邮件)并传递工作人员实体ID,以便RegisterEmployee命令处理程序可以在数据库中检索电话和地址字段以传递来汇总吗?
事件侧:
在事件方面,如果我的EmployeeRegistered事件处理程序必须投影员工的readmodel,是否需要事件本身具有所有信息才能构建readmodel?
或者我可以只将基本信息(名字,姓氏,电子邮件)和工作人员实体ID放入EmployeeRegistered事件的有效负载中,以便投影脚本自己在数据库中进行某种联接以检索一些复杂的隐藏信息吗? >
[编辑]
也许RegisterEmployee尝试做太多事情,我应该:
但是在那种情况下,这是否违反了在同一笔交易中应该发生注册动作的原则?如果我的RegisterEmployee成功而其他人没有成功怎么办?我最终会遇到不完整的员工注册流程?
[编辑2]
嗨,波拉,您说的没错。我的上下文发生在从旧版应用程序到cqrs一个(至少某些部分)的迁移中。
因此,我想让旧版应用程序做自己的事情,所以我只侦听db端的持久性事件,并从它们中调度域命令。
这就是为什么我可以想象有一个命令持有“仅持久”实体ID,以便不重复该命令中实体的字段并减轻负担。
答案 0 :(得分:2)
领域模型/设计中的某些功能已关闭。让我退后一步,勾勒出理想的方法,以便您可以绘制缺失的部分。
RegisterEmployee Command
包含Employee Aggregate
Employee Application Service
从Frontend接收命令Employee Application Service
初始化Employee Aggregate
,最好在工厂方法的帮助下进行Employee Aggregate
在成功验证和构造新的Employee对象时引发EmployeeRegistered Event
Employee Application Service
在Employee Repository
EmployeeRegistered Event
被调度到消息代理EmployeeRegistered Event
包含订户所需的整个数据集Subscribers
可以在相同的有界上下文(BC)中,也可以在不同的BC中。Interested Subscribers
赶上活动并在自己的BC中呼叫相关的Application Service
Application services
初始化基础结构服务并执行交易(在您的情况下,这是预测)事件处理程序中不应包含域逻辑。