调用域服务的基础架构存储库
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中。
长话短说,您可能可以在这里找到更好的职责分配。确切地说出哪一个很困难,因为我们缺少您实际希望此域服务执行的操作的详细信息。
我有一个应用程序服务 (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中。
长话短说,您可能可以在这里找到更好的职责分配。确切地说出哪一个很困难,因为我们缺少您实际希望此域服务执行的操作的详细信息。