求助:在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
相关产品推荐
相关产品推荐

