注入依赖关系层应用程序/域/存储库

时间:2018-05-03 11:27:04

标签: asp.net dependency-injection architecture domain-driven-design solid-principles

在使用DDD概念的应用程序中,如果有任何标准,我怀疑谁可以将(依赖)注入给定类的构造函数。

例如,在Application,Domain和Repository层之间。

1)需要注入用户的ClientAppService(应用层),是否应该注入UserApplicationService并从中调用UserService(Domain)或直接在ClientApplicationService中注入UserService?

2)在ClientService(域)中我应该注入UserService并从中调用UserRepository还是可以直接将UserRepository注入ClientService?

如果我正在注入对等类,我会关注循环引用。

但我也认为我不应该注入另一个实体的存储库,因为存储库的方法通常在服务中有一个必须先调用的规则。

有没有人有这个问题,你通常如何处理它?<​​/ p>

2 个答案:

答案 0 :(得分:1)

考虑关注点分离和责任分配,您应该准确注入您的工件所依赖的内容。这可能听起来有点明显,但它会更深一些。

考虑你的(2)例子:

  

在ClientService(域)中我应该注入UserService并从中调用UserRepository还是可以直接将UserRepository注入ClientService?

您可能应首先问问自己ClientService依赖哪种功能?

  • 如果它(ClientService)关心能够从它(ClientService)当前拥有的信息中找到用户,它应该可以直接接收UserRepository并且能够自己找到用户。

    < / LI>
  • 如果它(ClientService)需要用户,但它不具备查找用户所需的信息(此信息当前位于应用程序层级别),则ClientService可能应直接接收用户域对象,直接从应用程序级别使用存储库。

  • 如果它(ClientService)需要UserService的某些与域相关的功能作为其操作的一部分,那么在这种情况下,UserService可能会直接注入ClientService。

关于这个主题的其他可能的讨论可能是你真的需要所有这些域服务,如果你最好直接从应用层调用规则丰富的实体/聚合,它可能会使你的整体设计,注入模式和边界更简单。

此外,很多时候,您可能希望为工件而不是直接实例化工厂注入工厂。

可能会提出另一点:

  

但我也认为我不应该注入另一个实体的存储库,因为存储库的方法通常在服务中有一个必须先调用的规则。

这可能是您域内存在混淆的证据。存储库的作用应该围绕着“从可能的实体的范围中找到您的域实体&#34;”。从这个意义上讲,UserRepository使您能够从Universe中现有的用户中查找用户,因此它应该是一个非常孤立的操作,不应该依赖于服务或其他实体。如果用户存在,那么应该可以找到&#34; (并且可以持续存在,因为它是双向的)来自UserRepository。

在这种情况下,您不必担心在ClientService中注入UserRepository&#34;从教条的角度来看。如果客户端服务中的操作需要查找和使用用户实体,那么您应该可以这样做。你可能担心的是你的实体/总量是否设计得很好,或者你是否有某种错位的责任可能会引发这种情况/感觉&#34; &#34;我不应该把它注入那个&#34;。

答案 1 :(得分:0)

域实体和值对象几乎从不使用构造函数注入。

这是出于分离关注的动机;域模型中对象的责任是在内存表示中管理它们自己。

他们可能需要完成工作的其他功能作为参数传递给他们。

典型的机制是“域名服务”,由埃文斯在蓝皮书的第5章中描述。

草拟示例 - 假设我的订单汇总需要在订单项更改时更新其报价。我可以作为参数传入一个接受SKU并返回Price的接口。就Order而言,该查找正在“其他地方”发生。它不关心细节。 实现可能会加载另一个聚合来查找其当前状态,或者向某个远程系统发送消息,或者硬编码答案。

域服务实现通常会依赖应用程序或基础架构层提供的功能。