2017-05-15 37 views
0

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

+0

afaik在DDD只有服务应该消耗回购,而不是其他方式 –

+0

好的。你将如何实现我上面描述的? – pantonis

+0

你的'AppService'可以使用'DomainService'来检索数据。然后'DomainService'可以委派给'InfraRepo'来检索数据,然后过滤和应用规则,然后回到'AppService'。因此'InfraRepo'不再需要知道域业务逻辑,它可以专注于数据检索。 –

回答

1

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

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

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

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

2
  • 存储库实现驻留在较低的Infrastructure/Persistence/Data/...层中。如果一个存储库实现调用域服务,这意味着您将这种决策委托给较低层。顺便说一句,你也使它完全合法的另一个回购实施而不是调用服务。

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

  • 域服务不是过滤逻辑的最佳位置。通常您将过滤器作为参数传递给Repository或Query Service方法。

  • 业务逻辑可以在域服务中找到,但是如果您可以将它放在相关的实体或值对象中,则会更好。

长话短说,你可以在这里找到更好的责任分配。因为我们错过了你真正想要这个域服务做的事情的细节,所以知道哪一个很难。