如何在 CQRS 中构建分离和命名空间?
How to structure separation and namespaces in CQRS?
我正在寻找有关如何在 CQRS 结构化应用程序中构建命名空间的建议。
目前命令端和查询端在每个限界上下文中都在同一个命名空间中,但随着复杂性的增加,它开始产生问题。
当前该结构有以下文件夹,每个文件夹都包含实现:
Application
+ Api
+ Cli
+ Web
Domain
+ Action (Command and Command Handlers in one - we are not using a CommandBus)
+ Event
+ Model
+-- Project
|-- Project.file
|-- ProjectRepository.file
Infrastructure
+ Consumer (Projections and ProcessManagers)
+ EventStore
+ Persistance (Denormalized read side)
+-- Project
|-- SqlProjectRepository.file
Common (Supporting namespace)
现在的问题是领域模型当前同时包含实体和事件源聚合根,它们基本上分别只是查询端和命令端的一部分。
查询端和命令端的聚合没有重叠。
重构到分离,应该在哪里做分片?
建议 1
一个完整的切片导致一个查询和一个命令端,这意味着即使应用层也有读写端。
建议 2
仅在域层上制作的切片,以便查询端包含读取模型的(非常贫血的)实体,而命令端保存事件、事件源聚合根等。
如果我的不适用,请提出第三个建议。谢谢
Currently the structure has the following folders which each contains the implementation...
真不幸。
如果您安排名称空间以使一起更改的事物更靠近在一起,您可能会更愿意承担维护负担。您的 FrobMarbleRepository
属于 frobmarble
命名空间,而不属于 repository
命名空间。
我认为我不同意 Jimmy Bogard 在这里的完整分析,但是关注特征的教训很重要
https://jimmybogard.com/vertical-slice-architecture/
如果您碰巧需要在单个功能中为两个不同的想法使用相同的名称,那么您最终可能将该功能拆分为两个或更多名称空间;另一方面,需要重复使用一个名称可能表明您实际上正在处理多个功能。
这是我采用的方法 - 基于 CQRS 和 DDD,注意到我们的 DDD 扩展到具有单独的解决方案(.NET - 用于不同域限界上下文的 Web API)。
其次,我们所有的基础设施代码、授权处理和共享代码都是在私有包管理器中完成的,这消除了单个解决方案的一些混乱,我们在启动 (DI) 中对其进行 DI。另请注意,我们使用 EntityFramework 作为我们的数据库实现。
但是,考虑到这一点,我和我的团队是这样区分 CQRS 和 DDD 的。
+ App
+- Command
+-- Application.Command
+-- Data.Command.EntityFramework
+-- Domain.Command
+- Query
+-- Application.Query
+-- Data.Query.EntityFramework
+-- Domain.Query
+ Build
+- Pipeline
+ Database
+- Data.Database.EntityFramework
+- Data.Database.Model
+ Test
Api (API app)
Cli
我正在寻找有关如何在 CQRS 结构化应用程序中构建命名空间的建议。
目前命令端和查询端在每个限界上下文中都在同一个命名空间中,但随着复杂性的增加,它开始产生问题。
当前该结构有以下文件夹,每个文件夹都包含实现:
Application
+ Api
+ Cli
+ Web
Domain
+ Action (Command and Command Handlers in one - we are not using a CommandBus)
+ Event
+ Model
+-- Project
|-- Project.file
|-- ProjectRepository.file
Infrastructure
+ Consumer (Projections and ProcessManagers)
+ EventStore
+ Persistance (Denormalized read side)
+-- Project
|-- SqlProjectRepository.file
Common (Supporting namespace)
现在的问题是领域模型当前同时包含实体和事件源聚合根,它们基本上分别只是查询端和命令端的一部分。
查询端和命令端的聚合没有重叠。
重构到分离,应该在哪里做分片?
建议 1
一个完整的切片导致一个查询和一个命令端,这意味着即使应用层也有读写端。
建议 2
仅在域层上制作的切片,以便查询端包含读取模型的(非常贫血的)实体,而命令端保存事件、事件源聚合根等。
如果我的不适用,请提出第三个建议。谢谢
Currently the structure has the following folders which each contains the implementation...
真不幸。
如果您安排名称空间以使一起更改的事物更靠近在一起,您可能会更愿意承担维护负担。您的 FrobMarbleRepository
属于 frobmarble
命名空间,而不属于 repository
命名空间。
我认为我不同意 Jimmy Bogard 在这里的完整分析,但是关注特征的教训很重要
https://jimmybogard.com/vertical-slice-architecture/
如果您碰巧需要在单个功能中为两个不同的想法使用相同的名称,那么您最终可能将该功能拆分为两个或更多名称空间;另一方面,需要重复使用一个名称可能表明您实际上正在处理多个功能。
这是我采用的方法 - 基于 CQRS 和 DDD,注意到我们的 DDD 扩展到具有单独的解决方案(.NET - 用于不同域限界上下文的 Web API)。
其次,我们所有的基础设施代码、授权处理和共享代码都是在私有包管理器中完成的,这消除了单个解决方案的一些混乱,我们在启动 (DI) 中对其进行 DI。另请注意,我们使用 EntityFramework 作为我们的数据库实现。
但是,考虑到这一点,我和我的团队是这样区分 CQRS 和 DDD 的。
+ App
+- Command
+-- Application.Command
+-- Data.Command.EntityFramework
+-- Domain.Command
+- Query
+-- Application.Query
+-- Data.Query.EntityFramework
+-- Domain.Query
+ Build
+- Pipeline
+ Database
+- Data.Database.EntityFramework
+- Data.Database.Model
+ Test
Api (API app)
Cli