如何在AutoMapper自定义Resolver中注入依赖?解决构造函数报错
核心问题原因
你使用的Lazy静态AutoMapper实例会绕过依赖注入容器,AutoMapper只能通过无参构造函数创建Resolver实例,但你的MyCustomResolver依赖IOrderRepository且未定义无参构造,因此抛出MissingMethodException。
正确实现步骤
1. 移除静态Lazy的AutoMapper实例
放弃手动维护静态Mapper实例,让依赖注入容器接管AutoMapper的生命周期管理。
2. 注册AutoMapper到DI容器
在服务注册环节(比如WebAppMapping或Program.cs),使用AutoMapper官方扩展方法完成注册:
builder.Services.AddAutoMapper(typeof(MappingProfile));
该方法会自动扫描指定的Profile类,并将IMapper注册为Scoped服务。
3. 无需手动注册MyCustomResolver
不需要单独将MyCustomResolver注册为Transient,只要IOrderRepository已注册为Scoped,AutoMapper会自动通过DI容器获取Resolver的实例。
4. 通过构造函数注入IMapper使用
在需要映射的服务/类中,通过构造函数注入IMapper,替代静态实例调用:
private readonly IMapper _mapper; public YourBusinessService(IMapper mapper) { _mapper = mapper; } // 映射调用示例 var destModel = _mapper.Map<DestinationModel>(sourceModel);
5. 确保Resolver构造函数正确接收依赖
MyCustomResolver的构造函数需直接注入IOrderRepository:
public class MyCustomResolver : IValueResolver<SourceModel, DestinationModel, decimal> { private readonly IOrderRepository _orderRepo; public MyCustomResolver(IOrderRepository orderRepo) { _orderRepo = orderRepo; } public decimal Resolve(SourceModel source, DestinationModel destination, decimal destMember, ResolutionContext context) { // 执行数据库查询逻辑 return _orderRepo.GetTotalAmount(source.OrderId); } }
6. 在MappingProfile中正常配置Resolver
Profile中直接指定Resolver类型即可,AutoMapper会通过DI容器解析其依赖:
public class MappingProfile : Profile { public MappingProfile() { CreateMap<SourceModel, DestinationModel>() .ForMember(dest => dest.TotalAmount, opt => opt.MapFrom<MyCustomResolver>()); } }
为什么原有方式失效?
静态Lazy创建的Mapper实例完全脱离DI容器上下文,AutoMapper无法从容器中获取MyCustomResolver所需的IOrderRepository实例,只能尝试用无参构造创建Resolver,而你的Resolver并没有定义无参构造,因此触发报错。让DI容器管理IMapper后,AutoMapper会与DI体系集成,自动完成Resolver的依赖解析。
内容的提问来源于stack exchange,提问作者Shaggy

