如果我们考虑使用标准持久性存储库,那么解决方案很容易。我们将IStuffRepository放在Domain Layer中,将StuffRepositoryImplementation放在Infrastructure层中。
但是,当我们想要包装第三方API时,什么是好的模式?
我们可以应用相同的模式,在域层中使用IStuffGateway,在基础架构层中使用StuffGatewayImplementation。
但这种方法存在问题。当我们考虑持久层时,我们可以控制我们持久存在的数据。但是当我们考虑第三方API时,我们无法控制,这意味着我们可以尝试拥有一定的接口签名,但它必须受到我们正在包装的内容的影响。因此,如果我们更改实现(将第三方替换为另一方),接口签名可能会更改,并且域将被更改。
另一种方法可能是将界面移到域外,并将其置于Infrasture层中,并实现它。这样,应用层就可以毫无问题地使用它(并保持域完整)。但是这种方法从域中删除了重要的概念,从我的角度看这似乎很糟糕。
关于此的任何参考意见?
答案 0 :(得分:3)
我始终将Domain
个对象(Aggregates
)保持纯净,没有任何副作用。这意味着我没有从Domain
到任何其他图层的任何依赖关系。持久性/存储库始终位于Infrastructure
中。 Application
图层使用它来保留Aggregates
。
当我使用CQRS
时,我只保留我的写/命令端(Aggregates
)纯。 Readmodels
依赖于特定实现并进行了优化。我使用了很多MongoDB
来持久化。
当我不使用CQRS
时,我保持整个Aggregate
没有依赖(我别无选择,分割将是CQRS
)。
因此,在所有情况下,Domain
都没有IO
,它没有任何副作用。这主要是因为我需要能够在并发更新的情况下安全地重新执行Aggregate
上的命令。
如果您决定使用界面,则应使用DIP:Domain
拥有Interface
;这意味着域决定了方法的数量和签名。
答案 1 :(得分:2)
我在这里与康斯坦丁达成协议。
您仍然将概念保留在您的域中,而不是IO。应用程序层应提供所需的域对象。您可以调用反腐败层(IStuffGateway
)并获取所需的对象,然后通过对您的域的一些调用传入。
如果这是一项常见任务,您可能需要引入一个包装该应用程序的应用程序服务(IGetStuffAndCallDomainTask
)。