调用域服务的基础架构存储库

Infrastructure repository calling a domain service

我有一个应用程序服务 (AppService) 和一个从外部数据提供程序读取数据的基础结构存储库 (InfraRepo)。 AppService 向客户端调用 InfraRepo 和 returns 数据。 我有以下需求:我有一些过滤条件和业务逻辑。为此,我创建了一个域服务 (DomainService) 并将其注入到 InfraRepo 中。从外部数据提供程序(在 InfraRepo 中)检索数据后,我调用域服务,将数据传递到那里,然后取回结果。然后我 return 将结果返回到映射到 Dto 并 returned 到客户端的应用程序服务。 在基础架构存储库中调用域服务是否正确。

与其讨论纯粹的 DDD,不如将几个概念放在一起讨论以解决问题并强调每个概念的好处。

根据您对 DDD 的熟悉程度,此 article 提供了对 DDD 的良好概述。它将 DDD 构建块称为:实体、值对象、聚合(根)、服务、存储库和工厂。在问题中讨论了服务和存储库。没有讨论实体或值对象;因此我不确定存储库返回的数据。

讨论的洋葱架构可以解决这些元素如何相互作用 here。在这种情况下,它声明域应该处于核心位置,然后是域服务,然后是应用程序服务,最后是外层 UI、测试和基础架构。在此模型中,数据访问(存储库)是基础设施。所以关键是依赖从外层流向内层;也就是说,域不依赖于它自身以外的任何东西。这与传统的 3 层架构形成对比,传统的 3 层架构中一切都取决于数据访问代码,业务代码介于 UI 和数据访问代码之间。洋葱架构会说存储库 (InfraRepo) 属于外层,应用程序服务在下一层,域服务在下一层。因此,AppService 永远不会调用 InfraRepo,因为控制永远不会流向外层,而只能从外层流入。相反,AppService 会调用 DomainService,DomainService 会调用域(即业务逻辑)。域将利用它为数据访问定义的抽象(接口或纯虚拟 class)。 InfraRepo 将实现此抽象,理想情况下,域 class 将使用 IoC 容器来获取 InfraRepo 实例,同时仅了解接口。也就是说,IoC 容器就像上面提到的 DDD 构建块中的 Factory。

SOLID 原则已经存在了一段时间,它处理 class 设计的更精细方面以允许灵活和健壮的代码。在这种情况下,依赖倒置原则可以通过 IoC 容器实现,作为其使用的附加参数。此外,存储库接口的定义应牢记接口隔离原则。

  • 存储库实现驻留在较低的 Infrastructure/Persistence/Data/... 层中。如果一个存储库实现调用域服务,则意味着您将这种决策委托给较低层。顺便说一下,您还使另一个 Repo 实现完全合法 not 根本不调用该服务。

    这有点奇怪,因为在任何用例中,领域层通常都是您 总是 想要调用的东西。让基础架构负责调用或不调用域可能超出了它的范围。

  • 域服务不是过滤逻辑的最佳场所。通常您将过滤器作为参数传递给存储库或查询服务方法。

  • 业务逻辑可以在Domain Services中找到,但最好放在相关的Entity或Value Object中。

长话短说,您可能可以在这里找到更好的职责分配。确切地说出哪一个很困难,因为我们缺少您实际希望此域服务执行的操作的详细信息。