Skip to content

文章

何时使用 FromService 属性

2019年11月20日 • 4 分钟阅读

何时使用 FromService 属性

我最近发现了 [FromServices] 属性,它从 .Net Core 第一个版本开始就是其中的一部分。

[FromServices] 属性允许在 Asp.Net Core 控制器中进行方法级别的依赖注入。

这里是一个例子:

public class UserController : Controller
{
    private readonly IApplicationSettings _applicationSettings;

    public UserController(IApplicationSettings applicationSettings)
    {
        _applicationSettings = applicationSettings;
    }

    public IActionResult Get([FromService]IUserRepository userRepository, int userId)
    {
        //Do magic
    }
}

为什么使用方法注入而不是构造函数注入?常见的解释是当一个方法需要依赖项而在其他地方不使用时,那么它就是使用 [FromService] 属性的候选者。

来自 StackOverflowSteven 发表了一个反对使用 [FromService] 属性的回答

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

– 这样的 [FromServices] 属性很容易被遗忘,你只有在调用操作时才会发现(而不是在应用程序启动时发现,那时你可以验证应用程序的配置)

– 出于性能原因需要从构造函数注入转移的需求清楚地表明注入的组件创建起来太重,而注入构造函数应该是简单的,因此组件创建应该非常轻量级。

– 需要从构造函数注入转移以防止构造函数变得太大的需求表明你的类有太多依赖项并且变得太复杂。换句话说,有很多依赖项表明类违反了单一职责原则。你的控制器操作可以轻松地分布在不同类中的事实证明了这样的控制器不是很内聚的,因此是违反 SRP 的迹象。

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

顺便说一下,从可测试性的角度来看,如果有时有一个不需要的依赖项,这实际上不应该有什么关系。有有效的测试模式可以解决这个问题。

我同意 Steven 的观点;如果你需要将依赖项从控制器移动到方法,因为类构造了太多依赖项,那么是时候拆分控制器了。你几乎肯定违反了 SRP

我看到方法注入的唯一用例是延迟绑定,当依赖项在控制器构造时还没有准备好。否则,最好使用构造函数注入。

我这样说是因为使用构造函数注入,类在构造时就知道依赖项是否可用。而使用方法注入,情况并非如此,直到调用方法时才知道依赖项是否可用。

作者:Chuck Conway 专注于软件工程和生成式人工智能。在社交媒体上与他联系:X (@chuckconway) 或访问他的 YouTube

↑ 回到顶部

您可能还喜欢