【发布时间】:2015-02-06 12:40:02
【问题描述】:
在过去的几个月里,我们一直在使用 DDD 和 CQRS 实施应用程序。我仍然在努力解决的一件事是持久化数据的最佳方式,尤其是对于不同类型的多个数据源。
到目前为止,我们已经使用了一个 DAL 接口层,以及该 DAL 的多个部分实现。然后在我们的域层中,我们使用存储库来构造/保存我们的域对象到 n 个 DAL。这很好用,直到我们进行一些更高级的操作,如分页和搜索。这要求我们不仅要映射我们的数据,还要映射我们的排序/搜索/分页标准。
我读过一些意见,我们应该将持久层(IE 实体框架、文件系统、Web 服务)暴露给 DDD 层,并让存储库直接访问它们,这样他们就可以利用构建的功能进入诸如 ORM 之类的东西。这对我来说就像是一个泄漏的抽象。
是否有我忽略的模式可以帮助我们解决这些问题?
【问题讨论】:
-
存储库无论如何都应该存在于 DAL 中。所以他们可以而且应该知道你想到的功能。它们从领域层实现接口。这些接口必须不知道那些实现细节。
-
我一直将我们的 DDD 存储库编写为特定于域,而不是特定于数据。这意味着存储库获取并返回域对象。如果我在存储库上调用了 Get 方法,并且该域对象是由来自多个源的数据构成的,那将如何工作?基本上现在我们有两组“存储库”。适用于域的存储库,然后是返回特定于该实现中存储的数据的 DTO 的 DAL 实现。然后存储库 Dal 将这些 DTO 组装到域对象中。
-
我同意 repos 获取和返回域对象(具体来说,是聚合门,对吗?)。 DAL 取决于域。因此,在 DAL 的存储库实现中构造域聚合应该没有问题。您的问题似乎源于您的“写入”回购取决于“读取”回购 - 从而被屏蔽了您想要使用的特定于数据库的实施细节。
-
好的,所以我认为我的问题可能是 2 倍。 1)我需要在逻辑上分离我的读写回购定义。在域级别,我很少(如果有的话)需要列表、页面或搜索的能力。 2)我认为我的情况更微不足道,但现在我的存储库实现存在于我的域层中,并且所需的 DAL 被注入其中。因此,我的存储库依赖于 DAL,而不是相反。如果我要翻转依赖项,我仍然在为如何从多个 DAL 构建聚合根域对象而苦苦挣扎。
-
你的意思是 DAO 而不是 DAL,对吧? DAL 中的 L 代表“层”。请注意,您必须能够在一个事务中保存您的聚合。在您的情况下,这可能会或可能不会很棘手。如果除了一个数据源之外的所有数据源都是只读的,那应该不是问题。祝你好运!
标签: c# design-patterns repository domain-driven-design data-persistence