在“指南/电子书”中:“设计基础架构持久层”一节(第213页)中的.NET Microservices: Architecture for Containerized .NET Applications(与eShopOnContainers相关)一般说明了聚合根如何执行CUD操作针对持久性数据源。
提到了两个重要的起点:
不幸的是,在提到的所有其他示例中,聚合根和属于它的所有底层对象都在同一个持久数据源中。
模式如下:
我想扩展这种模式,聚合可以根据底层对象类型在2个或更多物理数据源上写入数据。
从起点1开始,根据底层对象的类型,将根聚合及其底层对象更新为不同的数据源是完全合理的。提到的示例包括:数据库和XML文件,数据库和NOSQL“数据库”,数据库和服务,数据库和物联网设备。因为聚合必须对持久性和基础设施的方法无知,所以我认为没有必要争论聚合的设计。我认为在书中没有写到聚合根应该在一个数据源中存在。
与此同时,起点2似乎也是完全合理的。因为编辑了聚合根目录中的完整对象集,所以整个包的成功持久性从一个存储库和(最好)来自一个工作单元进行协调。
问题是: 如果在聚合内部 - 根据底层对象的类型 - 它是否在不同的数据源上水合,如何处理领域驱动设计? 我应该使用一个自定义工作单元并决定在此UoW中写入何处?
我知道下一个question,但研究了code我认为它只涉及处理不同数据源的存储库的继承,但当时仍在服务一个数据源那不是我追求的。
答案 0 :(得分:2)
我想扩展这种模式,聚合可以根据底层对象类型在2个或更多物理数据源上写入数据。
你为什么要故意这样做?
在大多数情况下,选择持久性实现来为域提供服务,而不是相反。因此,快乐路径通常涉及选择一个持久性解决方案,该解决方案可以记录整个聚合的状态,并将整个事物存储在单个事务中。
因此,如果您发现自己试图将聚合存储在两个不同的地方,那么您应该仔细查看原因。
一个常见的答案是您希望能够有效地查询聚合状态。 cqrs是一种常见的解决方案 - 不是将聚合持久保存在两个不同的数据存储中,而是将其保留为一个并将其复制到另一个。查询可以非常有效地针对副本运行(尽管在更改聚合和查询结果中对该更改的反映之间存在一些额外的延迟。)
另一个常见的答案是,你确实有两个聚合,它们相互引用。将两个聚合存储在不同位置没有错。通过在代码中明确区分两者,可以更好地服务。
如果在聚合中如何处理域驱动设计 - 取决于底层对象的类型 - 它是否在不同数据源上水合?
很糟糕,就像其他人一样。