ASP.NET Core - 使用 [FromServices] 属性可能会带来哪些挑战或问题?

Bra*_*rad 5 c# dependency-injection asp.net-core

我在 ASP Core MVC 中有一个控制器。我正在尝试减少构造函数中的依赖注入服务,以便我可以更轻松地开始构建单元测试。但是,我注入了一些仅用于一两个控制器操作的服务。例如,我注入ILocationService是因为在我的一些操作中,我需要查找一个国家/地区Id编号并使用数据库获取 ISO Alpha-2 国家/地区代码(例如,将 ID 编号 1 映射到“CA”,将 2 映射到“US”,等等。)

Asp Core 支持该[FromServices]属性,因此我可以选择ILocationService直接注入到我的两个操作中,而不是将它们注入到控制器构造函数中。这样做的好处是我不需要总是ILocationService从每个单元测试中模拟/注入我的控制器,并且在编写单元测试时更清楚每个功能所依赖的服务。

现在明显的缺点是它不完全明显和清楚我的控制器依赖哪些服务,因为它们并没有全部分组在构造函数中。

是否存在使用该[FromServices]属性可能引起的任何其他特定挑战、问题或混淆点?

Ste*_*ven 7

您应该考虑这种类型的方法注入有一些不幸的缺点:

  • 这样的[FromServices]属性很容易被遗忘,您只会在调用操作时发现(而不是在应用程序启动时发现 - 或在单元测试期间 - 您可以在其中验证应用程序的配置)
  • 出于性能原因需要远离构造函数注入表明注入的组件太重而无法创建,而注入构造函数应该很简单,因此组件创建应该非常轻量级。
  • 需要摆脱构造函数注入以防止构造函数变得太大,这表明您的类有太多依赖项并且变得太复杂。换句话说,具有许多依赖项表明该类违反了单一职责原则。您的控制器操作可以很容易地拆分到不同的类这一事实证明这种控制器的内聚性不是很强,因此表明违反了 SRP。

因此,与其使用方法注入来隐藏根本问题,我建议在此处使用构造函数注入作为唯一的注入模式,并使您的控制器更小。然而,这可能意味着您的路由方案与您的类结构不同,但这完全没问题,并且完全受 ASP.NET Core 支持。

从可测试性的角度来看,顺便说一句,有时是否存在不需要的依赖关系并不重要。有一些有效的测试模式可以解决这个问题。