带有事件源的DDD应实时在哪个项目中读取模型(投影)?

时间:2019-06-26 14:08:30

标签: c# domain-driven-design cqrs event-sourcing

在典型的DDD架构中,我们有3个项目:

-没有引用

应用-它引用了域项目

基础结构-它引用了域项目

(+ Web / UI项目)

Domain模型当然可以在Domain项目中使用。但是应该在哪个项目中实时读取数据库(例如MongoDb)的模型(投影)?

3 个答案:

答案 0 :(得分:2)

没有成文法则规定读取模型应该存在于哪个项目中。以我个人的观点,我认为拥有一个单独的读取模型项目是有好处的。使用命令查询责任分离,如果应用程序的命令部分可以访问应用程序的查询部分,则事情会变得很混乱。我认为应该将两者明确分开。

我花了一些时间在一个示例项目上,该项目演示了如何设置DDD /端口和适配器/ CQRS应用程序。我已将代码放置在GitHub上:https://github.com/appie2go/steal-this-code

我还花了一些时间来解释我在以下文章中详细做出的选择:

希望有帮助!

欢呼

答案 1 :(得分:0)

简而言之,应用程序服务(应用程序层)和存储库(基础结构层)都知道READ模型。域层对底层的持久性和加载机制保持透明。

长答案,确切的使用机制取决于您如何使用读取模型。您可以使用它们来构造域层中使用的对象,或者更典型地,仅将其用作对API查询的响应。

第一种情况:将读取模型用作域层中的对象

应用程序服务将READ模型从资源库加载到域实体中。将READ模型正确地填充到域实体中是存储库的责任。该存储库还负责将域实体转换为WRITE模型以保留在主数据库中。

当您到达Domain模型时,对象已经在存储库的帮助下被加载到内存中。因此,域层甚至都不了解READ模型和WRITE模型;它只处理域实体。

第二种情况:使用读取模型存储对API查询的预先构建的响应

此方案是READ模型的更典型用法。通常,同一实体/聚合有多个读取模型,因为它们是针对特定API请求定制的。

在这种情况下,我们甚至都不会触摸域层。 Application Service接受请求,使用READ模型存储库加载对象,并将响应返回给应用程序服务器。

答案 2 :(得分:0)

说实话,这并不重要。面向DDD的实现或面向事件源的实现都没有默认结构

如果系统很小,则可以完美地拥有一个项目。如果您想使域中没有外部引用,可以将其保留在一个单独的项目中,并注意零引用,但需要一些支持域模型基础的东西,例如实体基类等。

读取模型和投影与领域模型完全正交,对于查询API或查询服务,通常需要它们。将读取的模型(在MongoDB中为文档)和投影保留在一个地方,您将受益匪浅。您可以从您的API项目中引用该项目,也可以将查询API,查询服务,查询模型,读取模型和投影放在一起。

同样,我会争辩说不存在“典型的DDD体系结构”之类的东西,因为DDD并不是一开始的体系结构。拆分项目更多地是为了开发人员的方便和纪律,而拆分系统是体系结构,而不是DDD特定的。

我想到的一件事是,如果您真的想DDD,那么您可能首先想知道上下文映射是什么,您真正需要多少域模型,也许在那里可以找到一些有关分离的想法,而不是真正基于技术上的考虑。