ASP.NET Core 2.0中AutoMapper IValueResolver依赖注入失效求助
嘿,我之前也卡在AutoMapper的IValueResolver依赖注入这里过,折腾了好一阵才弄明白,给你一步步讲清楚怎么解决:
第一步:创建带依赖注入的ValueResolver
首先你得写一个自己的Resolver类,把需要的IStorageService通过构造函数注入进去,别自己手动实例化服务:
public class YourCustomResolver : IValueResolver<SourceModel, DestinationModel, string> { private readonly IStorageService _storageService; // 构造函数注入依赖 public YourCustomResolver(IStorageService storageService) { _storageService = storageService; } public string Resolve(SourceModel source, DestinationModel destination, string destMember, ResolutionContext context) { // 这里就可以正常用_storageService的方法了 // 举个例子:return _storageService.GetFileUrl(source.FileId); } }
第二步:在MappingProfile中正确配置映射
重点:绝对不要在Profile里手动new你的Resolver! 那样会绕开依赖注入容器,导致里面的IStorageService为空。要让AutoMapper从服务容器里取实例,用MapFrom<YourResolverType>()的写法:
public class MappingProfile : Profile { public MappingProfile() { CreateMap<SourceModel, DestinationModel>() // 用泛型MapFrom指定Resolver类型,AutoMapper会自动从容器获取实例 .ForMember(dest => dest.TargetProperty, opt => opt.MapFrom<YourCustomResolver>()); } }
第三步:注册所有服务到依赖注入容器
确保你在Program.cs(或者Startup.cs)里把所有相关服务都注册好,包括AutoMapper、你的StorageService、还有Resolver:
// 先配置BlobServiceSettings builder.Services.Configure<BlobServiceSettings>(builder.Configuration.GetSection("BlobServiceSettings")); // 注册StorageService builder.Services.AddScoped<IStorageService, StorageService>(); // 注册AutoMapper并指定你的Profile所在的程序集 builder.Services.AddAutoMapper(typeof(MappingProfile)); // 注册你的自定义Resolver(如果AutoMapper没自动扫描到的话,一般AddAutoMapper会处理,但手动注册更稳妥) builder.Services.AddScoped<YourCustomResolver>();
第四步:通过依赖注入使用IMapper
最后,在需要用到映射的地方,通过构造函数注入IMapper实例,而不是自己创建:
public class SomeBusinessService { private readonly IMapper _mapper; public SomeBusinessService(IMapper mapper) { _mapper = mapper; } public DestinationModel MapModel(SourceModel source) { // 这里执行映射时,AutoMapper会自动注入Resolver需要的IStorageService return _mapper.Map<DestinationModel>(source); } }
常见坑提醒
很多人踩坑都是因为在Profile里写了new YourCustomResolver(),这种写法完全跳过了DI容器,Resolver里的依赖自然拿不到。一定要用泛型的MapFrom<>或者ResolveUsing(() => context.Mapper.ServiceProvider.GetRequiredService<YourCustomResolver>())(前者更简洁)。
内容的提问来源于stack exchange,提问作者NeroIsNoHero
相关产品推荐
相关产品推荐

