如何实现IReadOnlyReactiveProperty到目标类型的AutoMapper泛型映射?
解决AutoMapper映射IReactiveProperty到TDestination的嵌套场景问题
针对你遇到的嵌套IReactiveProperty<AnotherViewModel>到AnotherModel的映射问题,有两种可行的解决方案,核心都是让AutoMapper明确如何提取ReactiveProperty的Value并完成后续类型映射:
方案一:使用开放式泛型类型转换器
创建一个通用的类型转换器,专门处理IReadOnlyReactiveProperty<TSource>到任意TDestination的映射,AutoMapper会自动匹配泛型参数完成实例化:
public class ReactivePropertyConverter<TSource, TDestination> : ITypeConverter<IReadOnlyReactiveProperty<TSource>, TDestination> { public TDestination Convert(IReadOnlyReactiveProperty<TSource> source, TDestination destination, ResolutionContext context) { if (source == null) return default; // 提取ReactiveProperty的Value,再通过AutoMapper映射到目标类型 return context.Mapper.Map<TSource, TDestination>(source.Value); } }
在AutoMapper配置中注册这个开放式泛型转换器:
var mapperConfig = new MapperConfiguration(cfg => { // 注册开放式泛型转换器,覆盖所有IReadOnlyReactiveProperty<>到任意类型的映射 cfg.CreateMap(typeof(IReadOnlyReactiveProperty<>), typeof(object)) .ConvertUsing(typeof(ReactivePropertyConverter<,>)); // 配置常规的ViewModel与Model映射 cfg.CreateMap<AnotherViewModel, AnotherModel>(); cfg.CreateMap<ViewModel, Model>(); });
方案二:全局配置属性映射规则
如果不想额外编写转换器类,可以通过ForAllPropertyMaps全局配置所有ReactiveProperty类型成员的解析逻辑:
var mapperConfig = new MapperConfiguration(cfg => { // 筛选出所有类型为IReadOnlyReactiveProperty<>的源属性 cfg.ForAllPropertyMaps(map => map.SourceType.IsGenericType && typeof(IReadOnlyReactiveProperty<>).IsAssignableFrom(map.SourceType.GetGenericTypeDefinition()), (map, opts) => opts.ResolveUsing((src, dest, destMember, context) => { var reactiveProp = map.SourceMember.GetValue(src) as IReadOnlyReactiveProperty<object>; if (reactiveProp == null) return destMember; // 获取ReactiveProperty的Value,再映射到目标成员类型 var sourceValue = reactiveProp.Value; return context.Mapper.Map(sourceValue, sourceValue.GetType(), destMember.GetType()); })); // 常规映射配置 cfg.CreateMap<AnotherViewModel, AnotherModel>(); cfg.CreateMap<ViewModel, Model>(); });
原理说明
之前的问题本质是AutoMapper无法自动推断:需要先提取IReactiveProperty<TSource>的Value属性,再将TSource类型的实例映射到目标TDestination类型。上述两种方案都是明确告知AutoMapper这一流程,方案一更适合复用,方案二更灵活无需额外类。
内容的提问来源于stack exchange,提问作者Butzei
相关产品推荐
相关产品推荐

