如何将Automapper中自定义的List<KeyValuePair>映射泛型化?
实现泛型的KeyValuePair映射方案
没问题!要把你当前的KeyValuePair自定义映射改成可复用的泛型实现,让它能适配任意类型的键值对转换,咱们可以利用AutoMapper的开放泛型映射配置来搞定,具体步骤如下:
1. 配置泛型KeyValuePair映射规则
首先在AutoMapper的初始化配置中,注册一个通用的KeyValuePair<TSourceKey, TSourceValue>到KeyValuePair<TDestKey, TDestValue>的映射规则,它会自动处理任意类型的键和值的转换(前提是你已经注册了对应基础类型的映射):
// 如果是旧版静态Mapper方式 Mapper.Initialize(cfg => { // 注册开放泛型的KeyValuePair映射 cfg.CreateMap(typeof(KeyValuePair<,>), typeof(KeyValuePair<,>)) .ConstructUsing((sourceObj, context) => { // 获取源KeyValuePair的Key和Value var sourceType = sourceObj.GetType(); var sourceKey = sourceType.GetProperty("Key").GetValue(sourceObj); var sourceValue = sourceType.GetProperty("Value").GetValue(sourceObj); // 获取目标类型的泛型参数(TDestKey和TDestValue) var destType = context.DestinationType; var destKeyType = destType.GetGenericArguments()[0]; var destValueType = destType.GetGenericArguments()[1]; // 分别映射Key和Value到目标类型 var mappedKey = context.Mapper.Map(sourceKey, sourceType.GetGenericArguments()[0], destKeyType); var mappedValue = context.Mapper.Map(sourceValue, sourceType.GetGenericArguments()[1], destValueType); // 创建并返回目标KeyValuePair实例 return Activator.CreateInstance(destType, mappedKey, mappedValue); }); // 必须注册基础类型的映射(这一步不能忘!) cfg.CreateMap<MenuTable, Menu>(); cfg.CreateMap<RoleTable, Role>(); }); // 如果是新版依赖注入的MapperConfiguration方式(更推荐) var config = new MapperConfiguration(cfg => { cfg.CreateMap(typeof(KeyValuePair<,>), typeof(KeyValuePair<,>)) .ConstructUsing((sourceObj, context) => { // 同上的映射逻辑 var sourceType = sourceObj.GetType(); var sourceKey = sourceType.GetProperty("Key").GetValue(sourceObj); var sourceValue = sourceType.GetProperty("Value").GetValue(sourceObj); var destType = context.DestinationType; var destKeyType = destType.GetGenericArguments()[0]; var destValueType = destType.GetGenericArguments()[1]; var mappedKey = context.Mapper.Map(sourceKey, sourceType.GetGenericArguments()[0], destKeyType); var mappedValue = context.Mapper.Map(sourceValue, sourceType.GetGenericArguments()[1], destValueType); return Activator.CreateInstance(destType, mappedKey, mappedValue); }); cfg.CreateMap<MenuTable, Menu>(); cfg.CreateMap<RoleTable, Role>(); }); var mapper = config.CreateMapper();
2. 调用泛型映射
配置完成后,你调用映射的方式和之前完全一样,AutoMapper会自动匹配泛型规则:
// 静态方式 var result = Mapper.Map<List<KeyValuePair<Menu, List<Role>>>>(yourSourceList); // 实例方式 var result = mapper.Map<List<KeyValuePair<Menu, List<Role>>>>(yourSourceList);
3. 扩展复用性说明
这个泛型配置的好处在于一次配置,终身复用:
- 如果你以后需要转换其他类型的
KeyValuePair,比如KeyValuePair<UserTable, List<PermissionTable>>到KeyValuePair<User, List<Permission>>,只要注册UserTable→User和PermissionTable→Permission的基础映射,这个泛型规则就会自动生效,不用再写新的ConstructUsing。 - 对于集合类型的Value(比如
List<RoleTable>),AutoMapper默认已经支持集合到集合的转换,只要元素的映射存在,所以你不需要额外配置集合的映射规则。
内容的提问来源于stack exchange,提问作者SventoryMang
相关产品推荐
相关产品推荐

