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

.NET 4.8项目DI部署后突发Value cannot be null. Parameter name: provider错误

.NET 4.8依赖注入生产环境突发空引用异常排查与修复

问题场景

在.NET 4.8项目中引入Microsoft DependencyInjection NuGet包并完成DI配置后,生产环境运行数天无异常,但Elmah日志突然大量出现来自Application_BeginRequest方法的错误:

Value cannot be null. Parameter name: provider

现有DI配置代码

Startup.cs

[assembly: OwinStartupAttribute(typeof(Account.Startup))]
namespace Account {
    public partial class Startup {
        public void Configuration(IAppBuilder app) {
            ServiceCollection services = new ServiceCollection();
            //添加多个依赖项...
            //创建服务提供器
            IServiceProvider serviceProvider = services.BuildServiceProvider();
            //保存到静态字段
            DiClassStore.ServiceProvider = serviceProvider;
            DependencyResolver.SetResolver(mvcResolver);
        }
    }
}

Global.asax

protected void Application_BeginRequest(object sender, EventArgs e) {
    HttpContext.Current.Items[typeof(IServiceScope)] = DiClassStore.ServiceProvider.CreateScope();
}

protected void Application_EndRequest(object sender, EventArgs e) {
    IServiceScope scope = HttpContext.Current.Items[typeof(IServiceScope)] as IServiceScope;
    scope?.Dispose();
}

异常原因分析

  • 静态字段被意外置空:DiClassStore.ServiceProvider作为全局共享的静态字段,若有其他代码误操作修改该字段,会直接导致空引用。
  • 应用域重启时机问题:IIS应用池回收、配置更新等场景会触发应用重启,若第一个请求在Startup.Configuration初始化完成前到达,此时静态字段尚未赋值,调用CreateScope就会抛出异常。

修复方案

1. 增加空值检查与初始化校验

修改Global.asax的Application_BeginRequest方法,避免在容器未初始化时处理请求:

protected void Application_BeginRequest(object sender, EventArgs e) {
    if (DiClassStore.ServiceProvider == null) {
        HttpContext.Current.Response.StatusCode = 503;
        HttpContext.Current.Response.Write("服务初始化中,请稍后重试");
        HttpContext.Current.Response.End();
        return;
    }
    HttpContext.Current.Items[typeof(IServiceScope)] = DiClassStore.ServiceProvider.CreateScope();
}

2. 限制静态字段的赋值权限

修改DiClassStore类,确保服务提供器只能被初始化一次,防止意外修改:

public static class DiClassStore {
    private static IServiceProvider _serviceProvider;
    public static IServiceProvider ServiceProvider {
        get => _serviceProvider ?? throw new InvalidOperationException("DI容器未完成初始化");
        set => _serviceProvider ??= value; // 仅允许首次赋值
    }
}

3. 改用Owin中间件管理请求作用域

替代Global.asax的事件处理,通过Owin中间件绑定服务作用域与请求生命周期,可靠性更高:

public void Configuration(IAppBuilder app) {
    ServiceCollection services = new ServiceCollection();
    // 添加依赖项...
    IServiceProvider serviceProvider = services.BuildServiceProvider();
    DiClassStore.ServiceProvider = serviceProvider;

    // 注册作用域管理中间件
    app.Use(async (context, next) => {
        using (var scope = serviceProvider.CreateScope()) {
            context.Set(typeof(IServiceScope), scope);
            await next();
        }
    });

    DependencyResolver.SetResolver(mvcResolver);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 22:12:38