You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:在Asp.net Web Api2中使用Microsoft.Extension.DependencyInjection

适配传统ASP.NET WebApi的Microsoft.Extensions.DependencyInjection集成方案

我之前帮朋友解决过几乎一模一样的问题——在不引入OWIN的前提下,把微软的DI框架无缝接入传统ASP.NET WebApi项目,完全兼容依赖HttpContext.Current的第三方闭源库。下面是一套经过验证的可行方案:

1. 安装必要的NuGet包

首先在Package Manager Console中安装核心依赖包:

Install-Package Microsoft.Extensions.DependencyInjection
Install-Package Microsoft.Extensions.DependencyInjection.Abstractions

2. 创建DI容器配置类

新建一个静态类来统一管理服务注册和容器初始化:

using Microsoft.Extensions.DependencyInjection;

public static class DependencyInjectionConfig
{
    public static IServiceProvider ServiceProvider { get; private set; }

    public static void RegisterServices()
    {
        var services = new ServiceCollection();

        // 注册你的业务服务,示例:
        // 单例生命周期服务
        services.AddSingleton<IUserService, UserService>();
        // 请求级作用域服务(对应WebApi的单次请求生命周期)
        services.AddScoped<IOrderService, OrderService>();
        // 瞬时生命周期服务
        services.AddTransient<ILogger, ConsoleLogger>();

        // 自动注册项目中所有WebApi控制器(可选,也可以手动注册)
        services.AddControllersAsServices(typeof(WebApiApplication).Assembly.GetExportedTypes()
            .Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition)
            .Where(t => typeof(IHttpController).IsAssignableFrom(t)));

        // 构建最终的服务提供者
        ServiceProvider = services.BuildServiceProvider();
    }
}

3. 实现自定义WebApi依赖解析器

WebApi默认的依赖解析器不兼容Microsoft.Extensions.DependencyInjection,我们需要实现IDependencyResolver接口来完成桥接:

using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;
using Microsoft.Extensions.DependencyInjection;

public class ServiceProviderDependencyResolver : IDependencyResolver
{
    private readonly IServiceProvider _rootProvider;

    public ServiceProviderDependencyResolver(IServiceProvider rootProvider)
    {
        _rootProvider = rootProvider ?? throw new ArgumentNullException(nameof(rootProvider));
    }

    public object GetService(Type serviceType)
    {
        return _rootProvider.GetService(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _rootProvider.GetServices(serviceType);
    }

    public IDependencyScope BeginScope()
    {
        // 创建请求级别的服务作用域
        var scope = _rootProvider.CreateScope();
        return new ServiceProviderDependencyScope(scope);
    }

    public void Dispose()
    {
        // 根容器不需要在此释放
    }
}

public class ServiceProviderDependencyScope : IDependencyScope
{
    private readonly IServiceScope _scope;

    public ServiceProviderDependencyScope(IServiceScope scope)
    {
        _scope = scope ?? throw new ArgumentNullException(nameof(scope));
    }

    public object GetService(Type serviceType)
    {
        return _scope.ServiceProvider.GetService(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _scope.ServiceProvider.GetServices(serviceType);
    }

    public void Dispose()
    {
        // 释放请求级作用域
        _scope.Dispose();
    }
}

4. 在Global.asax中完成DI初始化

打开Global.asax.cs,在Application_Start方法中完成DI容器初始化和WebApi配置:

using System.Web.Http;

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        // 初始化DI服务容器
        DependencyInjectionConfig.RegisterServices();

        // 配置WebApi路由等基础设置
        GlobalConfiguration.Configure(WebApiConfig.Register);

        // 替换WebApi默认的依赖解析器为我们的自定义实现
        GlobalConfiguration.Configuration.DependencyResolver = 
            new ServiceProviderDependencyResolver(DependencyInjectionConfig.ServiceProvider);
    }
}

5. 在控制器中使用构造函数注入

现在你可以像在ASP.NET Core中一样,通过构造函数注入依赖:

public class OrdersController : ApiController
{
    private readonly IOrderService _orderService;

    // 构造函数注入依赖
    public OrdersController(IOrderService orderService)
    {
        _orderService = orderService;
    }

    // GET api/orders
    public IHttpActionResult Get()
    {
        var orders = _orderService.GetUserOrders();
        return Ok(orders);
    }
}

这个方案完全不依赖OWIN管道,不会干扰第三方库对HttpContext.Current的使用,同时完美适配传统ASP.NET WebApi的请求生命周期。

内容的提问来源于stack exchange,提问作者telli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:08:05