AutoMapper 6.2.2中反射获取TypeMap失败?原4.0.4可行代码失效
解决AutoMapper 6.2.2中无法通过反射获取TypeMap的问题
我之前也踩过AutoMapper版本迭代的坑,你遇到的问题本质是AutoMapper在升级过程中调整了内部私有成员的结构——4.0.4里的_typeMap私有字段在6.2.2版本中已经被移除或者重命名了,所以反射调用GetField会返回null。
优先推荐:使用AutoMapper官方公共API
依赖内部私有字段的代码非常脆弱,版本一更新就容易崩,所以最好用官方提供的公共方法来获取TypeMap。举两个实用的场景:
- 如果你已经有了
IMappingExpression<TSource, TDestination>实例,可以通过全局配置查找对应TypeMap:
var typeMap = Mapper.Configuration.FindTypeMapFor<TSource, TDestination>();
- 如果你是在自定义Profile中配置映射,也可以通过反射获取实现类的非公共属性来拿到TypeMap:
var mappingExpr = CreateMap<SourceModel, DestModel>(); var typeMapProperty = mappingExpr.GetType().GetProperty("TypeMap", BindingFlags.NonPublic | BindingFlags.Instance); var typeMap = (TypeMap)typeMapProperty.GetValue(mappingExpr);
6.2.2里MappingExpression(IMappingExpression的具体实现)确实存在这个非公共的TypeMap属性,比硬编码字段名靠谱得多。
迫不得已的方案:适配6.2.2的反射写法(不推荐)
如果因为业务限制必须用反射,那可以换一种方式——不硬编码字段名,而是通过字段类型来查找:
// 遍历所有私有实例字段,找到TypeMap类型的成员 var typeMapField = mappingExpression.GetType() .GetFields(BindingFlags.NonPublic | BindingFlags.Instance) .FirstOrDefault(f => f.FieldType == typeof(TypeMap)); if (typeMapField != null) { var typeMap = (TypeMap)typeMapField.GetValue(mappingExpression); // 后续业务逻辑 }
这种写法比固定字段名的兼容性稍好,但还是不如公共API稳定,毕竟AutoMapper的内部结构随时可能调整。
总之,尽量用官方提供的公共API,这才是长期可靠的解决方案。
内容的提问来源于stack exchange,提问作者Ramos
相关产品推荐
相关产品推荐

