AutoMapper无法创建自定义IMemberValueResolver实例问题求助
问题原因及解决办法
核心问题分析
- 泛型约束未满足:
FooCollectionResolver<TModel, TViewModel>对TModel的约束是where TModel : class, IPublishedElement,但你实际传入的FooCollectionModel并没有实现IPublishedElement接口。AutoMapper在反射创建解析器实例时会校验泛型约束,不满足则抛出实例创建失败的异常。 - 反射实例化的局限性:使用
MapFrom<TResolver>泛型方法时,AutoMapper默认通过无参构造反射创建解析器实例,既不会从DI容器获取实例,也无法处理需要依赖注入的解析器。即使约束满足,若后续解析器添加了依赖,这种方式仍会失效。
解决步骤
步骤1:满足泛型约束
修改FooCollectionModel,让它实现IPublishedElement接口:
public class FooCollectionModel : IPublishedElement { public string FooMember { get; set; } // 实现IPublishedElement接口要求的所有成员 }
步骤2:选择适配的映射配置方式
方式一:依赖注入兼容方案(推荐)
先将泛型解析器注册到DI容器,再配置AutoMapper从DI获取实例:
// 注册泛型解析器到DI services.AddTransient(typeof(FooCollectionResolver<,>)); // 配置AutoMapper services.AddAutoMapper(cfg => { cfg.AddMaps(new[] { "FooNamespace.Web", "FooNamespace.Web.Framework", }); // 告诉AutoMapper从DI容器获取服务实例 cfg.ConstructServicesUsing(type => services.BuildServiceProvider().GetService(type)); });
修改映射配置,使用非泛型的MapFrom重载指定解析器类型:
this.CreateMap<FooModel, FooViewModel>() .ForMember(dest => dest.BlockListModelMember, src => src.MapFrom( typeof(FooCollectionResolver<FooCollectionModel, FooCollectionViewModel>), s => s.BlockListModelMember));
方式二:直接传入解析器实例(无依赖场景)
如果你的解析器不需要依赖注入,可以直接创建实例传入:
var resolver = new FooCollectionResolver<FooCollectionModel, FooCollectionViewModel>(); this.CreateMap<FooModel, FooViewModel>() .ForMember(dest => dest.BlockListModelMember, src => src.MapFrom(resolver, s => s.BlockListModelMember));
验证
完成上述修改后重新运行程序,AutoMapper即可正确实例化解析器并完成映射。
内容的提问来源于stack exchange,提问作者DGibbs
相关产品推荐
相关产品推荐

