MapperHelper.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. using AutoMapper;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Reflection;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace Common
  10. {
  11. public static class MapperHelper
  12. {
  13. /// <summary>
  14. /// 同步锁
  15. /// </summary>
  16. private static readonly object Sync = new object();
  17. /// <summary>
  18. /// 将源对象映射到目标对象
  19. /// </summary>
  20. /// <typeparam name="TSource">源类型</typeparam>
  21. /// <typeparam name="TDestination">目标类型</typeparam>
  22. /// <param name="source">源对象</param>
  23. /// <param name="destination">目标对象</param>
  24. public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination)
  25. {
  26. return MapTo<TDestination>(source, destination);
  27. }
  28. /// <summary>
  29. /// 将源对象映射到目标对象
  30. /// </summary>
  31. /// <typeparam name="TDestination">目标类型</typeparam>
  32. /// <param name="source">源对象</param>
  33. public static TDestination MapTo<TDestination>(this object source) where TDestination : new()
  34. {
  35. return MapTo(source, new TDestination());
  36. }
  37. /// <summary>
  38. /// 将源对象映射到目标对象
  39. /// </summary>
  40. private static TDestination MapTo<TDestination>(object source, TDestination destination)
  41. {
  42. if (source == null)
  43. throw new ArgumentNullException(nameof(source));
  44. if (destination == null)
  45. throw new ArgumentNullException(nameof(destination));
  46. var sourceType = GetType(source);
  47. var destinationType = GetType(destination);
  48. var map = GetMap(sourceType, destinationType);
  49. if (map != null)
  50. return Mapper.Map(source, destination);
  51. lock (Sync)
  52. {
  53. map = GetMap(sourceType, destinationType);
  54. if (map != null)
  55. return Mapper.Map(source, destination);
  56. InitMaps(sourceType, destinationType);
  57. }
  58. return Mapper.Map(source, destination);
  59. }
  60. /// <summary>
  61. /// 获取类型
  62. /// </summary>
  63. private static Type GetType(object obj)
  64. {
  65. var type = obj.GetType();
  66. if ((obj is System.Collections.IEnumerable) == false)
  67. return type;
  68. if (type.IsArray)
  69. return type.GetElementType();
  70. var genericArgumentsTypes = type.GetTypeInfo().GetGenericArguments();
  71. if (genericArgumentsTypes == null || genericArgumentsTypes.Length == 0)
  72. throw new ArgumentException("泛型类型参数不能为空");
  73. return genericArgumentsTypes[0];
  74. }
  75. /// <summary>
  76. /// 获取映射配置
  77. /// </summary>
  78. private static TypeMap GetMap(Type sourceType, Type destinationType)
  79. {
  80. try
  81. {
  82. return Mapper.Configuration.FindTypeMapFor(sourceType, destinationType);
  83. }
  84. catch (InvalidOperationException)
  85. {
  86. lock (Sync)
  87. {
  88. try
  89. {
  90. return Mapper.Configuration.FindTypeMapFor(sourceType, destinationType);
  91. }
  92. catch (InvalidOperationException)
  93. {
  94. InitMaps(sourceType, destinationType);
  95. }
  96. return Mapper.Configuration.FindTypeMapFor(sourceType, destinationType);
  97. }
  98. }
  99. }
  100. /// <summary>
  101. /// 初始化映射配置
  102. /// </summary>
  103. private static void InitMaps(Type sourceType, Type destinationType)
  104. {
  105. try
  106. {
  107. var maps = Mapper.Configuration.GetAllTypeMaps();
  108. Mapper.Initialize(config =>
  109. {
  110. ClearConfig();
  111. foreach (var item in maps)
  112. config.CreateMap(item.SourceType, item.DestinationType);
  113. config.CreateMap(sourceType, destinationType);
  114. });
  115. }
  116. catch (InvalidOperationException)
  117. {
  118. Mapper.Initialize(config =>
  119. {
  120. config.CreateMap(sourceType, destinationType);
  121. });
  122. }
  123. }
  124. /// <summary>
  125. /// 清空配置
  126. /// </summary>
  127. private static void ClearConfig()
  128. {
  129. var typeMapper = typeof(Mapper).GetTypeInfo();
  130. var configuration = typeMapper.GetDeclaredField("_configuration");
  131. configuration.SetValue(null, null, BindingFlags.Static, null, CultureInfo.CurrentCulture);
  132. }
  133. /// <summary>
  134. /// 将源集合映射到目标集合
  135. /// </summary>
  136. /// <typeparam name="TDestination">目标元素类型,范例:Sample,不要加List</typeparam>
  137. /// <param name="source">源集合</param>
  138. public static List<TDestination> MapToList<TDestination>(this System.Collections.IEnumerable source)
  139. {
  140. return MapTo<List<TDestination>>(source);
  141. }
  142. }
  143. }