如何配置AutoMapper使用内置IoC容器构造依赖注入转换器
AutoMapper 配置构造函数注入自定义转换器的正确实现
你在Startup.ConfigureServices阶段拿不到最终的ServiceProvider是正常现象——这个阶段DI容器本身还在构建中,不需要强行提前生成容器实例,按以下两种方式配置即可:
推荐方案:使用官方DI扩展包(最简便)
直接用官方维护的AutoMapper.Extensions.Microsoft.DependencyInjection包,它已经内置了和ASP.NET Core DI容器的适配逻辑,不需要你手动编写ConstructServicesUsing的配置:
- 安装对应NuGet包
- 在
Startup.ConfigureServices中按顺序注册服务:- 先注册你自定义转换器依赖的所有业务服务,这部分和普通服务注册逻辑一致
- 注册AutoMapper,传入映射配置Profile所在的程序集即可
public void ConfigureServices(IServiceCollection services) { // 注册转换器需要注入的业务依赖 services.AddScoped<IMyBizService, MyBizService>(); // 注册自定义转换器,这步可省略:AddAutoMapper会自动扫描注册程序集内的转换器 services.AddTransient<ITypeConverter<SourceDto, DestinationEntity>, MyCustomConverter>(); // 注册AutoMapper,自动完成ConstructServicesUsing的容器适配 services.AddAutoMapper(typeof(Startup).Assembly); }
这种方式下,AutoMapper创建转换器实例时会自动从DI容器解析所需的构造函数依赖,不需要额外编码。
手动配置方案(不使用官方扩展包)
如果你需要手动控制MapperConfiguration的初始化逻辑,不要在ConfigureServices中提前调用BuildServiceProvider()——这种写法会生成独立的容器副本,导致单例服务重复创建的问题。正确做法是通过工厂模式注册IMapper,拿到容器构建完成后的正式ServiceProvider实例再做配置:
public void ConfigureServices(IServiceCollection services) { // 注册依赖服务和自定义转换器 services.AddScoped<IMyBizService, MyBizService>(); services.AddTransient<MyCustomConverter>(); // 通过工厂模式注册IMapper,入参sp就是容器构建完成后自动提供的ServiceProvider services.AddSingleton<IMapper>(sp => { var mapperConfig = new MapperConfiguration(cfg => { // 编写映射规则 cfg.CreateMap<SourceDto, DestinationEntity>().ConvertUsing<MyCustomConverter>(); // 配置服务解析逻辑,直接使用容器提供的sp实例 cfg.ConstructServicesUsing(serviceType => sp.GetRequiredService(serviceType)); }); // 可选:启动时立即校验映射配置有效性 mapperConfig.AssertConfigurationIsValid(); return mapperConfig.CreateMapper(); }); }
注意事项
- 自定义转换器的生命周期需要和它注入的服务生命周期匹配:如果注入的是Scoped生命周期的服务,转换器不要注册为Singleton,否则会触发依赖 captive 问题
- 只要转换器的构造函数参数都在DI容器中完成注册,AutoMapper会自动完成依赖注入,不需要手动传参创建转换器实例
内容的提问来源于stack exchange,提问作者Anton Minchenko
相关产品推荐
相关产品推荐

