AutoMapper如何添加自定义IObjectMapper?Wrapper<T>映射替代方案
实现Wrapper自动解包的解决方案
方案一:自定义IObjectMapper并手动注册
虽然MapperRegistry变为内部类,但仍可通过AutoMapper配置直接添加自定义IObjectMapper,全局处理Wrapper<T>到T的映射:
- 先定义示例
Wrapper<T>类:
public class Wrapper<T> { public T Value { get; set; } }
- 实现自定义
IObjectMapper:
public class WrapperObjectMapper : IObjectMapper { public bool IsMatch(TypePair context) { return context.SourceType.IsGenericType && context.SourceType.GetGenericTypeDefinition() == typeof(Wrapper<>) && context.DestinationType == context.SourceType.GetGenericArguments()[0]; } public object Map(object source, object destination, Type sourceType, Type destinationType, ResolutionContext context) { var valueProperty = sourceType.GetProperty(nameof(Wrapper<object>.Value)); return valueProperty.GetValue(source); } public Expression MapExpression(Type sourceType, Type destinationType, MemberMap memberMap, ResolutionContext context) { var sourceParam = Expression.Parameter(sourceType, "source"); var valueProp = Expression.Property(sourceParam, nameof(Wrapper<object>.Value)); return Expression.Lambda(valueProp, sourceParam); } }
- 在AutoMapper配置中注册该映射器:
var config = new MapperConfiguration(cfg => { cfg.Mappers.Add(new WrapperObjectMapper()); // 其他映射配置... }); var mapper = config.CreateMapper();
此方案会让全局所有Wrapper<T>到T的映射自动完成解包。
方案二:更优替代方案——通用类型转换器
相比自定义IObjectMapper,使用ITypeConverter实现更简洁,更贴合AutoMapper现代用法:
- 实现泛型类型转换器:
public class WrapperToValueConverter<T> : ITypeConverter<Wrapper<T>, T> { public T Convert(Wrapper<T> source, T destination, ResolutionContext context) { return source.Value; } }
- 在配置中注册通用映射规则:
var config = new MapperConfiguration(cfg => { cfg.CreateMap(typeof(Wrapper<>), typeof(object)).ConvertUsing(typeof(WrapperToValueConverter<>)); // 其他映射配置... });
这种方式无需处理复杂的IObjectMapper接口,仅聚焦转换逻辑,代码更简洁易维护。
方案三:全局映射规则批量处理
如果需要批量处理多种包装类映射,可通过ForAllMaps遍历所有映射规则自动添加解包逻辑:
var config = new MapperConfiguration(cfg => { cfg.ForAllMaps((map, exp) => { if (map.SourceType.IsGenericType && map.SourceType.GetGenericTypeDefinition() == typeof(Wrapper<>)) { exp.ConvertUsing((src, dest, ctx) => { var valueProp = src.GetType().GetProperty(nameof(Wrapper<object>.Value)); return valueProp.GetValue(src); }); } }); // 其他映射配置... });
内容的提问来源于stack exchange,提问作者Gofu
相关产品推荐
相关产品推荐

