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

升级DryIoc与Automapper后,如何正确注册Automapper?

DryIoc + AutoMapper 升级后注册问题解决方案

问题背景

DryIoc从4.8.8升级至5.4.1,AutoMapper从10.1.1升级至12.0.1后,原注册代码因ForAllMaps方法迁移调整为使用Internal(),但调用Mapper时触发DryIoc超时错误:

Error.WaitForScopedServiceIsCreatedTimeoutExpired; message: DryIoc has
waited for the creation of the scoped or singleton service by the
"other party" for the 3000 ticks without the completion. You may
call exception.TryGetDetails(container) to get the details of the
problematic service registration. The error means that either the
"other party" is the parallel thread which has started but is unable
to finish the creation of the service in the provided amount of time.
Or more likely the "other party" is the same thread and there is an
undetected recursive dependency or the scoped service creation is
failed with the exception and the exception was catched but you are
trying to resolve the failed service again. For all those reasons
DryIoc has a timeout to prevent the infinite waiting. You may change
the default timeout via
Scope.WaitForScopedServiceIsCreatedTimeoutTicks=NewNumberOfTicks

原注册代码(AutoMapper 10.x):

services.AddAutoMapper(options =>
{
    options.ForAllMaps((obj, options) => options.ForAllMembers(o => o.Condition((src, dest, member) => member != null)));
}, typeof(Responce<>));

调整后的代码(AutoMapper 12.x):

services.AddAutoMapper(options =>
{
    options.Internal().ForAllMaps((obj, options) => options.ForAllMembers(o => o.Condition((src, dest, member) => member != null)));
}, typeof(Responce<>));

正确注册方式及问题修复

1. 使用Profile类配置全局映射规则(推荐)

AutoMapper 12+将ForAllMaps移至Internal()内部,是官方不推荐直接在AddAutoMapper委托中修改全局规则,这种操作容易干扰容器初始化顺序,引发循环依赖或超时。

改用Profile类定义全局规则:

public class GlobalMappingProfile : Profile
{
    public GlobalMappingProfile()
    {
        // 全局映射规则:仅当成员不为null时执行映射
        ForAllMaps((map, mappingOpts) =>
        {
            mappingOpts.ForAllMembers(memberOpts => 
                memberOpts.Condition((src, dest, memberValue) => memberValue != null));
        });
    }
}

注册时指定Profile类和程序集:

// 同时加载GlobalMappingProfile和Responce<>所在程序集的映射配置
services.AddAutoMapper(typeof(GlobalMappingProfile), typeof(Responce<>));

2. 检查并修正服务生命周期

DryIoc 5.x对作用域服务的创建检测更严格,默认AddAutoMapper会将IMapper注册为单例。若你的映射配置依赖作用域服务(比如数据库上下文),单例的IMapper会在初始化时尝试获取作用域服务,导致超时或依赖冲突。

此时需显式将IMapper注册为作用域:

services.AddAutoMapper(typeof(GlobalMappingProfile), typeof(Responce<>))
       .AddScoped<IMapper>(sp => sp.GetRequiredService<Mapper>());

3. 排查递归依赖

调用错误提示中的exception.TryGetDetails(container)方法,获取具体的服务依赖链,定位是否存在循环依赖(比如:ServiceA依赖IMapper,而IMapper的映射配置又依赖ServiceA)。

4. 临时调整超时阈值(仅当确认无依赖问题时使用)

若映射初始化确实耗时较长,可临时调高DryIoc的超时时间:

// 调整超时为10000 ticks(约1秒,默认3000 ticks约0.3秒)
DryIoc.Scope.WaitForScopedServiceIsCreatedTimeoutTicks = 10000;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:33:16