【问题标题】:Infrastructure repository calling a domain service基础设施存储库调用域服务
【发布时间】:2017-05-15 09:04:45
【问题描述】:

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

【问题讨论】:

  • afaik 在 DDD 中只有服务应该使用 repos,而不是相反
  • 好的。您将如何实现我上面描述的内容?
  • 您的AppService 可以使用DomainService 来检索数据。然后DomainService 可以委托给InfraRepo 来检索数据,然后在返回到AppService 之前过滤和应用规则。这样InfraRepo就不再需要了解领域业务逻辑,可以专注于数据检索。
  • 所以我可以从域服务调用 InfraRepo?
  • 我想知道你的聚合根在哪里。

标签: domain-driven-design ddd-repositories ddd-service


【解决方案1】:
  • 存储库实现位于较低的基础架构/持久性/数据/...层。如果一个存储库实现调用域服务,则意味着您将这种决策委托给较低层。顺便说一句,您还让另一个 Repo 实现完全合法地调用该服务。

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

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

  • 业务逻辑可以在域服务中找到,但最好将其放置在相关的实体或值对象中。

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

【讨论】:

    【解决方案2】:

    与其单纯讨论 DDD,我们似乎可以将几个概念放在一起讨论以解决问题并突出每个概念的好处。

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-08
      • 1970-01-01
      • 2010-11-25
      • 2014-06-16
      • 1970-01-01
      • 2013-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多