AutoMapper如何配置类类型到dynamic的动态映射?
AutoMapper 类类型到dynamic动态映射实现方案
- AutoMapper内置的
ToDynamicMapper默认仅支持静态约定的属性映射,要实现运行时动态配置,需要自定义实现IObjectMapper接口的映射器,配合MapperConfiguration的运行时配置逻辑完成需求。 - 核心实现步骤:
- 自定义映射器替换或补充默认的
ToDynamicMapper逻辑,映射器内部判断目标类型为dynamic或ExpandoObject时,从当前上下文读取你提前存入的动态字段映射规则。 - 构造
MapExpression时,直接生成向ExpandoObject字典结构写入属性值的表达式即可:将返回的ExpandoObject强转为IDictionary<string, object>,按照你的动态配置规则,把源类型对应属性的值逐个赋值到字典的对应Key中。 - 配置Mapper时通过
AddMapper方法把自定义映射器注册到配置中,优先级要高于内置的ToDynamicMapper,避免被默认逻辑覆盖。
- 自定义映射器替换或补充默认的
- 核心代码示例:
// 自定义映射器核心实现 public class CustomToDynamicMapper : IObjectMapper { public bool IsMatch(TypePair context) => context.DestinationType == typeof(ExpandoObject) || context.DestinationType == typeof(object); public Expression MapExpression(IGeneratorConfiguration generatorConfiguration, TypePair typePair, Expression sourceExpression, Expression destExpression, Expression contextExpression) { // 读取你提前存储的对应源类型的动态映射规则 var mappingRules = GetDynamicMappingRules(typePair.SourceType); var expandoVar = Expression.Variable(typeof(ExpandoObject), "expando"); var dictVar = Expression.Variable(typeof(IDictionary<string, object>), "dict"); var assignExpressions = new List<Expression> { Expression.Assign(expandoVar, Expression.New(typeof(ExpandoObject))), Expression.Assign(dictVar, Expression.Convert(expandoVar, typeof(IDictionary<string, object>))) }; foreach (var rule in mappingRules) { var getSourceValue = Expression.Property(sourceExpression, rule.SourcePropertyName); var addToDict = Expression.Call(dictVar, typeof(IDictionary<string, object>).GetMethod("Add", new[] { typeof(string), typeof(object) }), Expression.Constant(rule.DestFieldName), Expression.Convert(getSourceValue, typeof(object))); assignExpressions.Add(addToDict); } assignExpressions.Add(expandoVar); return Expression.Block(new[] { expandoVar, dictVar }, assignExpressions); } }
- 映射器注册方式:
var config = new MapperConfiguration(cfg => { // 优先注册自定义映射器 cfg.AddMapper<CustomToDynamicMapper>(); // 其他业务配置逻辑 });
- 补充说明:如果需要支持嵌套类型映射,只需要在生成赋值表达式的时候递归调用
Mapper.Map方法的表达式即可,无需完全自行实现嵌套逻辑。
内容的提问来源于stack exchange,提问作者Klaus P.
相关产品推荐
相关产品推荐

