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

ASP.NET Core+Autofac中二次Mediator调用触发ObjectDisposedException求助

问题描述

在一个方法内执行两次Mediator调用时,第二次调用总是触发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

简化代码

MainLogic.cs(注册为Transient)

private readonly IDateTimeProvider _dateTimeProvider; // 注册为Singleton
private readonly IMediator _mediator; // Autofac默认注册为Transient

public MainLogic(IDateTimeProvider dateTimeProvider, IMediator mediator)
{
    _dateTimeProvider = dateTimeProvider;
    _mediator = mediator;
}

public async Task<List<myObj>> MainProcessingLogic(string key, List<SomeObj> listOfItems, DateTime dateTime)
{
    try
    {
        var myVar = (await _mediator.Send(new ProcessSomeQuery(key, listOfItems, dateTime))).FirstOrDefault();
    }
    catch (Exception ex)
    {
        _logger.LogError("ProcessSomeQuery ran into an error : " + ex);
    }

    try
    {
        var myVar = await _mediator.Send(new ProcessSomeOtherDifferentQuery(key, listOfItems, dateTime));
    }
    catch (Exception ex)
    {
        _logger.LogError("ProcessSomeOtherDifferentQuery ran into an error : " + ex);
    }
    // ...其他代码
}

ProcessSomeQueryHandler(依赖IMyDataBaseContext,Autofac默认注册为Transient)

private readonly IMyDataBaseContext _myDatabaseContext;
private readonly ILogger<ProcessSomeQueryHandler> _logger;

public ProcessSomeQueryHandler(IMyDataBaseContext myDatabaseContext, ILogger<ProcessSomeQueryHandler> logger)
{
        _myDatabaseContext = myDatabaseContext;
        _logger = logger;
}

ProcessSomeOtherDifferentQueryHandler(仅依赖Logger)

private readonly ILogger<ProcessSomeOtherDifferentQueryHandler> _logger;

public ProcessSomeOtherDifferentQueryHandler(ILogger<ProcessSomeOtherDifferentQueryHandler> logger)
{
  _logger = logger;
}

异常现象

  • 仅第二次Mediator调用报错;调换调用顺序后,原第一个调用会在第二次执行时报错
  • 两次调用同一ProcessSomeQuery,第二次仍会报错
  • 无论第二个查询是否注入数据库上下文,第二次调用均报错
  • 调整各类作用域配置无效
  • 移除ProcessSomeQuery的数据库上下文注入后,无报错

服务注册配置

services.AddTransient<IMainLogic, MainLogic>();
services.AddSingleton<IDateTimeProvider, DateTimeProvider>();
// IMediator由Autofac注册,默认Transient
// MyDataBaseContext由Autofac注册,默认Transient

解决方案

1. 移除手动释放数据库上下文的代码

检查ProcessSomeQueryHandler的实现,若存在手动调用_myDatabaseContext.Dispose()的逻辑,必须删除。Autofac会自动管理依赖实例的生命周期,手动释放会导致该实例绑定的作用域被标记为已释放,后续所有依赖该作用域的操作都会抛出异常。

2. 调整Mediator和数据库上下文的生命周期为Scoped

将IMediator和IMyDataBaseContext注册为InstancePerLifetimeScope(即Scoped),确保同一作用域内的实例复用且作用域存活期间实例有效:

// Autofac注册代码
builder.RegisterType<Mediator>().As<IMediator>().InstancePerLifetimeScope();
builder.RegisterType<MyDataBaseContext>().As<IMyDataBaseContext>().InstancePerLifetimeScope();

3. 在独立作用域内执行两次Mediator调用

如果当前上下文没有现成的活跃作用域,可手动创建一个作用域,确保两次调用都在同一作用域内执行:

修改MainLogic注入ILifetimeScope

private readonly IDateTimeProvider _dateTimeProvider;
private readonly ILifetimeScope _lifetimeScope;

public MainLogic(IDateTimeProvider dateTimeProvider, ILifetimeScope lifetimeScope)
{
    _dateTimeProvider = dateTimeProvider;
    _lifetimeScope = lifetimeScope;
}

在方法内使用作用域执行调用

public async Task<List<myObj>> MainProcessingLogic(string key, List<SomeObj> listOfItems, DateTime dateTime)
{
    using (var scope = _lifetimeScope.BeginLifetimeScope())
    {
        var scopedMediator = scope.Resolve<IMediator>();
        try
        {
            var myVar = (await scopedMediator.Send(new ProcessSomeQuery(key, listOfItems, dateTime))).FirstOrDefault();
        }
        catch (Exception ex)
        {
            _logger.LogError("ProcessSomeQuery ran into an error : " + ex);
        }

        try
        {
            var myVar2 = await scopedMediator.Send(new ProcessSomeOtherDifferentQuery(key, listOfItems, dateTime));
        }
        catch (Exception ex)
        {
            _logger.LogError("ProcessSomeOtherDifferentQuery ran into an error : " + ex);
        }
    }
    // ...其他代码
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:02:33