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

如何让AutoMapper映射对象列表时复用自定义转换器实例

问题原因

默认调用services.AddAutoMapper(assemblies)进行AutoMapper服务注册时,程序集扫描到的自定义ITypeConverter、IValueResolver等映射组件,会被默认注册为**瞬态(Transient)**生命周期。在映射集合类型时,每个元素的转换逻辑都会单独触发一次转换器的服务解析,因此每次都会生成新的转换器实例。

解决方案

根据你当前的代码场景(转换器依赖Scoped生命周期的ISomeService),最适配的方案是显式指定自定义转换器的DI生命周期,让AutoMapper从DI容器解析转换器时遵循你指定的生命周期规则,实现实例复用。

方案1:显式注册转换器为Scoped生命周期(推荐,适配当前场景)

在ConfigureServices方法中,在AddAutoMapper调用后追加自定义转换器的Scoped生命周期注册即可,AutoMapper不会覆盖你手动指定的服务生命周期:

services.AddScoped<ISomeService, SomeService>();
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
// 追加这行,指定转换器为Scoped生命周期
services.AddScoped<FromToTypeConverter>();

配置后,在同一个DI作用域(例如ASP.NET Core的单个HTTP请求)内,所有映射操作都会复用同一个FromToTypeConverter实例,和你注入的ISomeService生命周期完全匹配,不会出现依赖逃逸问题。

方案2:直接传入转换器实例(仅适合无Scoped依赖的场景)

如果你的转换器没有Scoped依赖,也可以在映射配置时直接传入已经实例化好的转换器对象,AutoMapper会全局复用这一个实例:

// 注意:需要自行手动提供构造函数所需的所有依赖
var converter = new FromToTypeConverter(loggerInstance, someServiceInstance);
CreateMap<From, To>().ConvertUsing(converter);

注意:该方式注册的转换器是全局单例的,如果持有Scoped生命周期的服务,会出现依赖被异常持有、对象已释放访问错误、跨请求状态污染等问题,不要在当前依赖Scoped服务的场景下使用。

注意事项
  • 不要将持有Scoped依赖的转换器注册为Singleton生命周期,否则会产生Captive Dependency(长生命周期对象持有短生命周期对象)问题,引发服务异常。
  • 显式注册转换器时,生命周期必须大于等于其依赖服务的生命周期,你当前场景下Scoped是最优选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:54:23