ASP.NET Core-使用[FromServices]属性是不好的做法吗?

时间:2019-02-12 18:03:24

标签: c# asp.net-core dependency-injection

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

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

明显的缺点是它现在还不是很明显,也不清楚控制器所依赖的服务,因为这些服务并未全部分组在构造函数中。

使用的是[FromServices]不良习惯还是强烈的代码异味指示?

1 个答案:

答案 0 :(得分:0)

对我来说,在控制器动作中使用这种类型的方法注入是一个坏主意,因为:

  • 这种[FromServices]属性很容易被遗忘,您只会在调用该动作时才知道(而不是在应用程序启动时发现,您可以在其中验证应用程序的配置)
  • 出于性能方面的考虑,需要退出构造函数注入,这清楚地表明,注入的组件过于繁琐而无法创建,而injection constructors should be simple和组件创建因此应该非常轻巧。
  • 需要远离构造函数注入,以防止构造函数变得太大,这表明您的类具有过多的依赖关系,并且变得过于复杂。换句话说,具有许多依赖性表示该类违反了Single Responsibility Principle。您的控制器动作可以很容易地划分为不同的类,这一事实证明该控制器的凝聚力不是很高,因此表明存在违反SRP的迹象。

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

顺便说一句,从可测试性的角度来看,有时是否不需要依赖关系并不重要。有effective test patterns可以解决此问题。