DDD-第三方API接口应该在哪里?

Nor*_*ard 5 domain-driven-design ddd-repositories ddd-service

如果考虑使用标准的持久性存储库,则解决方案很简单。我们将IStuffRepository放在域层中,并将StuffRepositoryImplementation放在基础结构层中。

但是,当我们要包装第三方API时,好的模式是什么?

我们可以应用相同的模式,在域层具有IStuffGateway,在基础结构层具有StuffGatewayImplementation。

但是这种方法存在问题。当我们考虑持久层时,我们可以控制我们所持久的数据。但是,当我们考虑使用第三方API时,我们无法控制,这意味着我们可以尝试具有特定的接口签名,但是它必须受包装的内容的影响。因此,如果我们更改实现(用另一个替换第三方),则接口签名可能会更改,并且域也会更改。

另一种方法可能是将接口移出域,并随其实现一起放入基础架构层。这样,应用程序层可以毫无问题地使用它(并保持域完整)。但是这种方法从领域中删除了重要的概念,在我看来,这似乎很糟糕。

对此有任何参考意见吗?

Con*_*enu 7

我总是保持我的Domain对象 ( Aggregates) 纯净,没有副作用。这意味着我没有从Domain到任何其他层的任何依赖项。持久性/存储库始终位于Infrastructure. 该Application层使用它来持久化Aggregates.

当我使用 时CQRS,我只保持我的写/命令端 ( Aggregates) 纯。的Readmodels依赖和优化,具体的实现。最近我用了很多MongoDB坚持。

当我不使用 时CQRS,我保持整体Aggregate没有依赖关系(我别无选择,拆分将是CQRS)。

所以,在所有情况下,Domain都没有任何作用IO,它没有副作用。这主要是因为我需要能够Aggregate在并发更新的情况下安全地重新执行命令。

但是,如果您决定使用接口,则应使用DIPDomain拥有Interface; 这意味着域决定了方法的数量和签名

  • 我认为我没有正确表达自己,因为我从来不想暗示我的域依赖于其他层。我所说的是我的存储库接口(IStuffRepository 在我的域层中声明。实现(StuffRepository)位于基础设施层中。问题在于包装我对外部 API 的访问的接口的位置。 (2认同)
  • 这适用于数据存储库。但我的问题与持久性存储库无关。对于封装对第三方 API 的访问的接口,情况并非如此。想象一个支付网关,您需要提供一个 clientId 作为 Guid。这种第三方问题直接泄漏到您的域中。在您更改支付提供商的那一天,您可能需要一个 clientId 作为整数。这让我感到困惑,因为域层应该是放置 IPaymentGateway 接口的合适位置,因为它代表了有界上下文的用例。 (2认同)

Ebe*_*oux 2

我在这里同意康斯坦丁的观点。

仍然可以将概念保留在您的域中,但不能保留 IO。应用层应该提供所需的领域对象。您可以调用反腐败层 ( IStuffGateway) 并获取所需的对象,然后通过对域的某些调用传入这些对象。

如果这是一项常见任务,您可能需要引入一个IGetStuffAndCallDomainTask包装该位的应用程序服务 ( )。