AutoMapper 创建嵌套对象映射

之前在做DTO转换时,用到AutoMapper。但DTO的层次太深了,无奈官方没针对嵌套类型提供好的解决方案,于是自己实现了一下:

思路:采用递归和反射很好的避免手工创建嵌套对象的映射。

 

第一个版本,已经提交到:https://github.com/AutoMapper/AutoMapper/wiki/Nested-mappings

技术分享
 1         /// <summary>
 2         /// 递归创建类型间的映射关系 (Recursively create mappings between types)
 3         ///created by cqwang
 4         /// </summary>
 5         /// <param name="sourceType"></param>
 6         /// <param name="destinationType"></param>
 7         public static void CreateNestedMappers(Type sourceType, Type destinationType)
 8         {
 9             PropertyInfo[] sourceProperties = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
10             PropertyInfo[] destinationProperties = destinationType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
11             foreach (var destinationProperty in destinationProperties)
12             {
13                 Type destinationPropertyType = destinationProperty.PropertyType;
14                 if (Filter(destinationPropertyType))
15                     continue;
16 
17                 PropertyInfo sourceProperty = sourceProperties.FirstOrDefault(prop => NameMatches(prop.Name, destinationProperty.Name));
18                 if (sourceProperty == null)
19                     continue;
20 
21                 Type sourcePropertyType=sourceProperty.PropertyType;
22                 if (destinationPropertyType.IsGenericType)
23                 {
24                     Type destinationGenericType = destinationPropertyType.GetGenericArguments()[0];
25                     if (Filter(destinationGenericType))
26                         continue;
27 
28                     Type sourceGenericType = sourcePropertyType.GetGenericArguments()[0];
29                     CreateMappers(sourceGenericType, destinationGenericType);
30                 }
31                 else
32                 {
33                     CreateMappers(sourcePropertyType, destinationPropertyType);
34                 }
35             }
36 
37             Mapper.CreateMap(sourceType, destinationType);
38         }
39 
40         /// <summary>
41         /// 过滤 (Filter)
42         /// </summary>
43         /// <param name="type"></param>
44         /// <returns></returns>
45         static bool Filter(Type type)
46         {
47             return type.IsPrimitive || NoPrimitiveTypes.Contains(type.Name);
48         }
49 
50         static readonly HashSet<string> NoPrimitiveTypes = new HashSet<string>() { "String", "DateTime", "Decimal" };
51 
52         private static bool NameMatches(string memberName, string nameToMatch)
53         {
54             return String.Compare(memberName, nameToMatch, StringComparison.OrdinalIgnoreCase) == 0;
55         }
View Code

 

后来自测中发现,要过滤的一些结构体可能很多,比较麻烦,所以自己又完善了下,有了第二个版本

技术分享

第二个版本在公司内的一些服务中已经使用并上线,挺好。因为并未涉及到公司内的任何业务信息,只是简单的思路和实现,所以这里贴出来给大家分享一下。

所有代码为原创,转载请注明出处。

 

其实,本没有路,走过去,便是路。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。