Domain driven design DDD-第三方API接口应该在哪里? 如果考虑标准持久性存储库,则解决方案很简单。我们将IStuffRespository放在域层,将StuffRespository实现放在基础架构层

Domain driven design DDD-第三方API接口应该在哪里? 如果考虑标准持久性存储库,则解决方案很简单。我们将IStuffRespository放在域层,将StuffRespository实现放在基础架构层,domain-driven-design,ddd-repositories,ddd-service,Domain Driven Design,Ddd Repositories,Ddd Service,但是,当我们想要包装第三方API时,好的模式是什么 我们可以应用相同的模式,在域层有一个IStuffGateway,在基础设施层有一个StuffGateway实现 但这种方法存在一个问题。当我们考虑持久层时,我们控制着我们坚持的数据。但是,当我们考虑第三方API时,我们没有控制,这意味着我们可以尝试拥有某种接口签名,但是它必须受到我们正在包装的东西的影响。因此,如果我们更改实现(用另一个第三方替换第三方),接口签名可能会更改,域也会更改 另一种方法是将接口移到域外,并将其与实现一起放在基础设施层

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

我们可以应用相同的模式,在域层有一个IStuffGateway,在基础设施层有一个StuffGateway实现

但这种方法存在一个问题。当我们考虑持久层时,我们控制着我们坚持的数据。但是,当我们考虑第三方API时,我们没有控制,这意味着我们可以尝试拥有某种接口签名,但是它必须受到我们正在包装的东西的影响。因此,如果我们更改实现(用另一个第三方替换第三方),接口签名可能会更改,域也会更改

另一种方法是将接口移到域外,并将其与实现一起放在基础设施层。这样,应用层就可以毫无问题地使用它(并保持域的完整性)。但这种方法从领域中删除了重要的概念,从我的角度来看,这似乎是不好的


关于这方面的任何参考意见?

我始终保持我的
对象(
聚合
)的纯净,没有副作用。这意味着我没有从
到任何其他层的任何依赖关系。持久性/存储库始终位于
基础结构中。
应用程序
层使用它来持久化
聚合

当我使用
CQRS
时,我只保持写/命令端(
Aggregates
)的纯净。
Readmodels
依赖于特定的实现,并针对特定的实现进行了优化。最近我使用了很多
MongoDB
来实现持久性

当我不使用
CQRS
时,我保持整个
聚合
,没有依赖项(我没有选择,拆分将是
CQRS

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


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

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

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


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

我想我没有正确地表达自己,因为我从来都不想暗示我的域是其他层的依赖项。我说的是我的存储库接口(IStuffRepository)在我的域层中声明位于基础架构层。问题是关于包装我对外部API访问的接口的位置。您确实正确地表达了自己。这就是我所说的。外部持久性不应影响域模型。您的存储库接口应具有相同的签名(加载、保存、删除)当外部持久性更改时。该接口的位置应保留在域层内。这对于数据存储库是正确的。但我的问题与持久性存储库无关。对于包装对第三方API的访问的接口,情况并非如此。想象一下,在支付网关中,您需要提供clientId作为Guid。这个第三方问题直接泄漏到您的域中。在您更改支付提供商的那天,您可能需要一个作为整数的clientId。这让我很困惑,因为域层应该是放置IPaymentGateway接口的合适位置,因为它代表有界上下文的用例。然后您应该导入反腐败层我不确定如果这是真正的答案(反腐败层),为什么这是公认的答案我的问题与包装第三方API的接口的位置有关。通常,存储库接口位于域中,实现位于基础结构层。但当涉及包装外部API的接口时,应用相同模式存在一些缺点,因为缺少对签名的控制。因为它不是一个真正的域,所以不应该在那里定义接口,不。也许你的ACL会是一个更合适的位置。所以你是说我的域根本不应该知道外部API周围包装器的一些接口签名?这意味着应用层将是唯一的p请注意这一点(通过基础架构层的反腐败层)当编排一个完整的业务用例时……这肯定会起作用,但我仍然觉得域应该知道一些事情。但调用外部API通常不涉及任何业务逻辑,并且是应用层中业务用例的一部分。您的域可能会有本地定义/对象例如,假设您正在调用某个返回有效地址的地址网关。您所依赖的域中很可能仍然有一个
地址
。应用层将进行调用并返回,例如,映射的
地址
MyGatewayImplementation.Fetch(“streetName”,streetNumber)
…它将从内部映射,例如,从web服务调用返回的
addrObj
。您怎么办