我对CQRS / DDD很新,所以我的理解可能会有很大漏洞。
但是,假设我有一个聚合对象Widget
。 Widget
由Note
个对象组成,Note
个对象可以附加File
个对象。
在CQRS中,我可能有一个名为AddNoteToWidget
的命令。我从阅读中知道命令和事件对象都应该是简单的DTO(我知道它们也可以有其他形式,但关键是它们不包含任何行为)。
我也理解实体永远不应该包含对存储库的引用,因为它们应该是不知道的持久性。
我的AddNoteToWidget
是否包含对File
对象的引用,只是与命令一起序列化?如果是这种情况,那么我的File
对象应该是一个值对象。但是,我已将其建模为具有自己的存储库的实体,因为我希望在整个系统中拥有集中一致的文件存储。
答案 0 :(得分:4)
通过阅读您的问题及其评论,很明显您目前将File
视为子实体和聚合根。这是一个问题,你应该决定两个中的一个:
File
模型作为聚合。现在,只有File
的ID必须在该聚合之外使用,而不是File
本身。此外,通过自己的存储库检索File
个对象。File
模型作为Widget
聚合中的实体。这意味着只要有Widget
,就可以随时使用该文件。 File
个对象没有自己的存储库,它们通过Widget
与WidgetRepository
一起加载。在你的情况下哪两个更好,我无法从你的问题中得知。作为指导原则,聚合边界是一致性边界,聚合总是以原子方式持久化。应用服务应该只修改单个聚合。
我认为您目前的主要问题可归纳如下:
存储库仅处理整个聚合,绝不会处理属于聚合的实体。
当然,可能只有一个实体组成的简单聚合,在这种情况下,实体和聚合是相同的。