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

DI上下文已释放后,如何在后台线程中使用AutoMapper?

问题分析

你遇到的问题根源在于:通过DI注入的IMapper实例可能绑定了请求作用域的上下文——要么是AutoMapper本身被注册为作用域服务,要么是你的映射配置(Profile)中依赖了作用域内的服务,导致AutoMapper在后台任务执行时仍尝试访问已释放的请求作用域。

解决方案

1. 手动注册单例模式的IMapper

绕过默认的AddAutoMapper扩展,直接注册一个不依赖请求作用域的单例IMapper实例,确保它在应用启动时就完成初始化,后续无需访问DI容器:

services.AddSingleton<IMapper>(sp =>
{
    var config = new MapperConfiguration(cfg =>
    {
        // 添加上你的所有映射Profile
        cfg.AddProfile<YourMappingProfile>();
        cfg.AddProfile<AnotherProfile>();
    });
    // 验证配置正确性(可选,但建议开启)
    config.AssertConfigurationIsValid();
    return config.CreateMapper();
});

这种方式创建的IMapper完全独立于请求作用域,不会绑定任何DI上下文。

2. 清理映射配置中的作用域依赖

检查你的Profile实现,确保没有在映射逻辑中依赖作用域内的服务(比如通过ConstructUsing或ResolveUsing从DI获取服务)。如果必须使用外部依赖,改为在映射时通过参数传入:

// 错误示例(依赖DI作用域)
cfg.CreateMap<Source, Dest>()
   .ConstructUsing(sp => new Dest(sp.GetRequiredService<IScopedService>()));

// 正确示例(映射时传入依赖)
cfg.CreateMap<Source, Dest>()
   .ForMember(d => d.Property, opt => opt.MapFrom((src, dest, _, context) => 
       context.Items["RequiredService"].DoSomething(src)));

// 后台任务中使用时传入依赖
var dest = mapper.Map<Source, Dest>(source, opt => 
    opt.Items["RequiredService"] = preResolvedService);

3. 在后台任务中创建独立的Mapper实例

如果无法修改全局注册方式,可以在服务类中注入IMapperConfigurationProvider,然后在后台任务里基于配置创建新的IMapper实例——这个实例不会绑定原请求作用域:

public class YourService
{
    private readonly IMapperConfigurationProvider _mapperConfig;

    public YourService(IMapperConfigurationProvider mapperConfig)
    {
        _mapperConfig = mapperConfig;
    }

    public Task<IActionResult> YourApiMethod()
    {
        // 启动后台任务
        _ = Task.Run(() =>
        {
            // 创建独立的Mapper实例
            var mapper = _mapperConfig.CreateMapper();
            // 使用mapper执行映射操作
            var result = mapper.Map<Source, Dest>(yourSourceData);
        });

        return Task.FromResult<IActionResult>(Ok());
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 16:18:19