IT俱乐部 ASP.NET ASP.NET Core中获取注入服务的所有方式

ASP.NET Core中获取注入服务的所有方式

总览

# 方式 使用场景 推荐度
1 构造函数注入 Controller、Service、ViewComponent ⭐⭐⭐⭐⭐
2 Action 方法参数注入 Controller Action ⭐⭐⭐⭐
3 @inject 指令 Razor 视图 ⭐⭐⭐
4 HttpContext.RequestServices 手动获取(不推荐常用) ⭐⭐
5 IServiceProvider / IServiceScopeFactory 后台任务、动态创建 ⭐⭐⭐
6 Middleware 的 Invoke 参数 中间件 ⭐⭐⭐⭐
7 ActivatorUtilities 手动 new 对象时 ⭐⭐
8 属性注入 [FromServices] Controller 属性 ⭐⭐

1. 构造函数注入(最主流)

public class HomeController : Controller
{
    private readonly IFriendService _friendService;
    private readonly ILogger _logger;

    // ✅ 通过构造函数注入,框架自动解析
    public HomeController(IFriendService friendService, ILogger logger)
    {
        _friendService = friendService;
        _logger = logger;
    }

    public async Task Index()
    {
        var friends = await _friendService.GetAllAsync();
        return View(friends);
    }
}

适用于:Controller、Service、Repository、ViewComponent、Middleware 类、HostedService 等所有由 DI 容器管理的类。

2. Action 方法参数注入

public class HomeController : Controller
{
    // ✅ 只在某个 Action 中需要,不必污染构造函数
    public async Task Friends([FromServices] IFriendService friendService)
    {
        var friends = await friendService.GetAllAsync();
        return View(friends);
    }
}

[FromServices] 可省略(ASP.NET Core 对接口类型参数默认从 DI 解析),但写上更明确。

3. Razor 视图中@inject

@using MyApp.Services
@inject IFriendService FriendService
@inject IOptions Settings

好友数:@await FriendService.GetCountAsync()

应用名称:@Settings.Value.AppName

视图中尽量只做简单取值,不要写复杂业务逻辑,否则应改用 ViewComponent。

4. 从HttpContext.RequestServices手动获取

public class HomeController : Controller
{
    public IActionResult Index()
    {
        // ⚠️ 不推荐,但在某些特殊场景下不得不用
        var friendService = HttpContext.RequestServices.GetRequiredService();
        var friends = friendService.GetAll();
        return View(friends);
    }
}

典型使用场景:在静态方法、事件回调、或无法使用构造函数注入的地方。

5. 注入IServiceProvider/IServiceScopeFactory

public class OrderProcessingService : IOrderProcessingService
{
    private readonly IServiceScopeFactory _scopeFactory;

    public OrderProcessingService(IServiceScopeFactory scopeFactory)
    {
        _scopeFactory = scopeFactory;
    }

    public async Task ProcessOrderAsync(int orderId)
    {
        // ✅ 在后台线程中创建新的作用域(因为 Scoped 服务不能跨线程共享)
        using var scope = _scopeFactory.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService();
        var order = await dbContext.Orders.FindAsync(orderId);
        // ...
    }
}

典型场景:BackgroundService、Timer 回调、Task.Run 中需要 Scoped 服务。

6. Middleware 的Invoke/InvokeAsync参数注入

public class RequestLoggingMiddleware
{
    private readonly RequestDelegate _next;

    // 构造函数:只能注入 Singleton 服务
    public RequestLoggingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    // ✅ Invoke 方法参数:可以注入 Scoped/Transient 服务(每次请求解析)
    public async Task InvokeAsync(HttpContext context, ILogger logger)
    {
        logger.LogInformation("Request: {Path}", context.Request.Path);
        await _next(context);
    }
}

7.ActivatorUtilities(手动创建实例)

// 当你需要手动 new 一个类,但又想让 DI 帮你注入依赖
var myService = ActivatorUtilities.CreateInstance(serviceProvider, "额外参数");

典型场景:工厂模式、动态创建类型实例。

8. 属性注入([FromServices])

public class HomeController : Controller
{
    // ✅ 属性注入(仅 Controller 支持)
    [FromServices]
    public IFriendService FriendService { get; set; }

    public IActionResult Index()
    {
        var friends = FriendService.GetAll();
        return View(friends);
    }
}

不推荐,隐藏了依赖关系,不利于测试。

选择指南

你在哪里需要服务?
│
├── Controller / Service / ViewComponent / HostedService
│       → ✅ 构造函数注入
│
├── 只有某一个 Action 需要
│       → ✅ [FromServices] 方法参数注入
│
├── Razor 视图中简单取值
│       → ✅ @inject(复杂逻辑改用 ViewComponent)
│
├── Middleware
│       → 构造函数(Singleton)+ Invoke 参数(Scoped)
│
├── 后台线程 / Timer / Task.Run
│       → ✅ IServiceScopeFactory.CreateScope()
│
├── 静态方法 / 无法注入的地方
│       → ⚠️ HttpContext.RequestServices(最后手段)
│
└── 手动 new 对象
        → ActivatorUtilities.CreateInstance()

常见陷阱

陷阱 说明
Singleton 中注入 Scoped ❌ 会导致 Scoped 服务变成 Singleton 生命周期(Captive Dependency)
在 Task.Run 中直接用构造函数注入的 DbContext ❌ 跨线程不安全,应用 IServiceScopeFactory 新建作用域
在视图中 @inject 后写大量业务逻辑 ❌ 应抽到 ViewComponent 或 ViewModel 中
用 GetService() 不判空 ⚠️ 服务未注册时返回 null,应用 GetRequiredService() 直接抛异常

以上就是ASP.NET Core中获取注入服务的所有方式的详细内容,更多关于ASP.NET Core获取注入服务的资料请关注IT俱乐部其它相关文章!

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/code/asp-net/18654.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部