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

ASP.NET MVC5 Owin应用修改Autofac配置后,应用关闭时容器提前销毁导致清理逻辑失效的问题排查与咨询

ASP.NET MVC5 Owin应用修改Autofac配置后,应用关闭时容器提前销毁导致清理逻辑失效的问题排查与咨询

我们团队维护着一个基于ASP.NET MVC5、OWIN、Web API 2和SignalR的应用,使用Autofac作为依赖注入容器。最近我们调整了OWIN的配置,目的是让OWIN中间件和Web API 2控制器共享同一个生命周期范围——把原来在GlobalConfiguration.Configuration.DependencyResolver设置Autofac解析器的方式,改成了在OWIN里用新的HttpConfiguration()实例来配置。

结果这一改,应用关闭和会话结束时的清理逻辑直接崩了,每次尝试通过全局Autofac容器解析服务时都会抛出ObjectDisposedException:

System.ObjectDisposedException: Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it (or one of its parent scopes) has already been disposed.

我们排查后发现是Autofac的根容器销毁得太早了,导致我们的清理代码根本没法在它销毁前执行(或者说我们不知道怎么让清理代码跑在前面)。目前观察到的应用关闭时的事件顺序是:

  1. Autofac根容器被销毁(由AutofacWebApiDependencyResolver触发)
  2. 执行OWIN的ShuttingDown回调代码
  3. 触发MvcApplication.Session_End
  4. 触发MvcApplication.Application_End

现在我们有几个核心疑问想请教各位:

  • 这次配置修改到底哪里出了问题?
  • 怎么才能让清理服务的代码在Autofac容器销毁前执行?
  • 为什么AutofacWebApiDependencyResolver会主动销毁根容器?
  • 为什么在这次“破坏性修改”之前,容器不会在Session_End前被销毁?

下面是修改前后的代码对比,方便大家定位问题:

之前能正常工作的版本(清理逻辑无异常)

Global.asax.cs

protected void Application_Start() 
{
    var container = ConfigureAutofac();
    AutofacHelper.Container = container;

    GlobalHost.DependencyResolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container);
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}

protected void Session_End(Object sender, EventArgs e) 
{
    AutofacHelper.Container.Resolve<ILockService>().ReleaseLocksBySessionId(Session.SessionID);
}

protected void Application_End() 
{
    AutofacHelper.Container.Resolve<ILockService>().ReleaseAllLocks();
}

Startup.cs

public void Configuration(IAppBuilder app) 
{
    app.UseAutofacMiddleware(AutofacHelper.Container);

    ConfigureSession(app); // 初始化会话配置
    ConfigureOAuth(app);

    // 配置SignalR
    app.MapSignalR();

    // 配置认证后逻辑
    ConfigurePostAuthentification(app);
}

修改后出问题的版本

Global.asax.cs

protected void Application_Start() 
{
    var container = ConfigureAutofac();
    AutofacHelper.Container = container;

    GlobalHost.DependencyResolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container);
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    // 注释掉了原来的GlobalConfiguration配置,改成在OWIN里设置Web API解析器
    // GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}

protected void Session_End(Object sender, EventArgs e) 
{
    AutofacHelper.Container.Resolve<ILockService>().ReleaseLocksBySessionId(Session.SessionID);
}

protected void Application_End() 
{
    AutofacHelper.Container.Resolve<ILockService>().ReleaseAllLocks();
}

Startup.cs

public void Configuration(IAppBuilder app) 
{
    // ***** 尝试在Autofac容器销毁前执行清理代码,但没用,这个回调还是跑在容器销毁之后 *****
    var context = new OwinContext(app.Properties);
    var token = context.Get<CancellationToken>("host.OnAppDisposing");
    if (token != CancellationToken.None) 
    {
        token.Register(() => 
        {
            Console.WriteLine("Unfortunately this is called after autofac container disposal.");
        });
    }

    // 配置Autofac与用户上下文
    app.UseAutofacMiddleware(AutofacHelper.Container);
    app.UseAutofacMvc();

    var config = new HttpConfiguration();
    config.DependencyResolver = new AutofacWebApiDependencyResolver(AutofacHelper.Container);

    // 注册NodaTime类型
    var formatters = config.Formatters;
    var jsonFormatter = formatters.JsonFormatter;
    var settings = jsonFormatter.SerializerSettings;
    settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);

    WebApiConfig.Register(config);
    app.UseAutofacWebApi(config);

    ConfigureSession(app);
    ConfigureOAuth(app);

    // 配置SignalR
    app.MapSignalR();

    // 配置认证后逻辑
    ConfigurePostAuthentication(app);

    app.UseWebApi(config);
}

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 07:23:08