12

如果我们考虑一个标准的持久性存储库,那么解决方案很简单。我们将 IStuffRepository 放在领域层,将 StuffRepositoryImplementation 放在基础设施层。

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

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

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

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

对此有参考意见吗?

4

2 回答 2

8

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

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

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

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

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

于 2017-05-31T05:29:15.353 回答
2

我同意康斯坦丁的观点。

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

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

于 2017-05-31T06:25:35.157 回答