MapperConfiguration.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. using Masuit.Tools.Mapping.Exceptions;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Linq.Expressions;
  6. namespace Masuit.Tools.Mapping.Core
  7. {
  8. /// <summary>
  9. /// 主映射器
  10. /// </summary>
  11. /// <typeparam name="TSource">源类型</typeparam>
  12. /// <typeparam name="TDest">目标类型</typeparam>
  13. public class MapperConfiguration<TSource, TDest> : MapperConfigurationBase
  14. {
  15. /// <summary>
  16. ///
  17. /// </summary>
  18. protected readonly IList<Action<TSource, TDest>> actionsAfterMap;
  19. /// <summary>
  20. /// 构造函数
  21. /// </summary>
  22. public MapperConfiguration(string paramName, string mapperName = null) : base(typeof(TSource), typeof(TDest), paramName, mapperName)
  23. {
  24. actionsAfterMap = new List<Action<TSource, TDest>>();
  25. }
  26. /// <summary>
  27. /// 获取Lambda表达式树
  28. /// </summary>
  29. /// <returns></returns>
  30. public Expression<Func<TSource, TDest>> GetLambdaExpression()
  31. {
  32. return Expression.Lambda<Func<TSource, TDest>>(GetMemberInitExpression(), paramClassSource);
  33. }
  34. /// <summary>
  35. /// 获取委托
  36. /// </summary>
  37. /// <returns></returns>
  38. public Func<TSource, TDest> GetFuncDelegate()
  39. {
  40. return (Func<TSource, TDest>)GetDelegate();
  41. }
  42. /// <summary>
  43. /// 映射成员
  44. /// </summary>
  45. /// <param name="getPropertySource">源类型</param>
  46. /// <param name="getPropertyDest">目标类型</param>
  47. /// <returns></returns>
  48. public MapperConfiguration<TSource, TDest> ForMember<TPropertySource, TPropertyDest>(Expression<Func<TSource, TPropertySource>> getPropertySource, Expression<Func<TDest, TPropertyDest>> getPropertyDest)
  49. {
  50. // 添加到映射列表并且可以继续操作
  51. ForMemberBase(getPropertySource.Body, getPropertyDest.Body, false);
  52. return this;
  53. }
  54. /// <summary>
  55. /// 映射成员
  56. /// </summary>
  57. /// <typeparam name="TPropertySource">属性源类型</typeparam>
  58. /// <typeparam name="TPropertyDest">属性目标类型</typeparam>
  59. /// <param name="getPropertySource">源类型</param>
  60. /// <param name="getPropertyDest">目标类型</param>
  61. /// <param name="checkIfNull">是否检查null值</param>
  62. /// <returns></returns>
  63. public MapperConfiguration<TSource, TDest> ForMember<TPropertySource, TPropertyDest>(Expression<Func<TSource, TPropertySource>> getPropertySource, Expression<Func<TDest, TPropertyDest>> getPropertyDest, bool checkIfNull)
  64. {
  65. // 添加到映射列表并且可以继续操作
  66. ForMemberBase(getPropertySource.Body, getPropertyDest.Body, checkIfNull);
  67. return this;
  68. }
  69. /// <summary>
  70. /// 映射成员
  71. /// </summary>
  72. /// <typeparam name="TPropertySource">属性源类型</typeparam>
  73. /// <typeparam name="TPropertyDest">属性目标类型</typeparam>
  74. /// <param name="getPropertySource">源类型</param>
  75. /// <param name="getPropertyDest">目标类型</param>
  76. /// <param name="mapperName">mapper别名</param>
  77. /// <returns></returns>
  78. public MapperConfiguration<TSource, TDest> ForMember<TPropertySource, TPropertyDest>(Expression<Func<TSource, TPropertySource>> getPropertySource, Expression<Func<TDest, TPropertyDest>> getPropertyDest, string mapperName)
  79. {
  80. // 添加到映射列表并且可以继续操作
  81. ForMemberBase(getPropertySource.Body, getPropertyDest.Body, true, mapperName);
  82. return this;
  83. }
  84. /// <summary>
  85. /// 忽略一些不需要映射的成员
  86. /// </summary>
  87. /// <param name="propertyDest">属性名</param>
  88. /// <returns></returns>
  89. public MapperConfiguration<TSource, TDest> Ignore<TProperty>(Expression<Func<TDest, TProperty>> propertyDest)
  90. {
  91. return IgnoreBase(propertyDest) as MapperConfiguration<TSource, TDest>;
  92. }
  93. /// <summary>
  94. /// 映射后要执行的操作
  95. /// </summary>
  96. /// <param name="actionAfterMap">映射后要执行的操作</param>
  97. /// <returns></returns>
  98. public MapperConfiguration<TSource, TDest> AfterMap(Action<TSource, TDest> actionAfterMap)
  99. {
  100. // 添加到映射列表并且可以继续操作
  101. actionsAfterMap.Add(actionAfterMap);
  102. return this;
  103. }
  104. /// <summary>
  105. /// 执行后续操作。
  106. /// </summary>
  107. /// <param name="source">源类型</param>
  108. /// <param name="dest">目标类型</param>
  109. public void ExecuteAfterActions(TSource source, TDest dest)
  110. {
  111. if (actionsAfterMap.Count > 0)
  112. {
  113. foreach (var action in actionsAfterMap)
  114. {
  115. if (action == null)
  116. {
  117. throw new NoActionAfterMappingException();
  118. }
  119. action(source, dest);
  120. }
  121. }
  122. }
  123. /// <summary>
  124. /// 反向映射
  125. /// </summary>
  126. /// <param name="name">mapper别名</param>
  127. /// <returns>
  128. /// 新的mapper对象
  129. /// </returns>
  130. /// <exception cref="MapperExistException"></exception>
  131. public MapperConfiguration<TDest, TSource> ReverseMap(string name = null)
  132. {
  133. var map = GetMapper(typeof(TDest), typeof(TSource), false, name);
  134. if (map != null)
  135. {
  136. throw new MapperExistException(typeof(TDest), typeof(TSource));
  137. }
  138. string finalName = string.IsNullOrEmpty(name) ? "s" + (MapperConfigurationCollectionContainer.Instance.Count).ToString() : name;
  139. map = new MapperConfiguration<TDest, TSource>(finalName);
  140. MapperConfigurationCollectionContainer.Instance.Add(map);
  141. CreateCommonMember();
  142. // 现有属性的映射,并且创建反向关系
  143. foreach (var item in PropertiesMapping.Where(item => GetPropertyInfo(item.Item1).CanWrite))
  144. {
  145. if (!string.IsNullOrEmpty(item.Item4))
  146. {
  147. //找到反向关系的mapper
  148. var reverseMapper = GetMapper(item.Item2.Type, item.Item1.Type, false);
  149. if (reverseMapper != null)
  150. {
  151. map.ForMemberBase(item.Item2, item.Item1, item.Item3, reverseMapper.Name);
  152. }
  153. }
  154. else
  155. {
  156. if (item.Item1.NodeType == ExpressionType.MemberAccess)
  157. {
  158. map.ForMemberBase(item.Item2, item.Item1, item.Item3, item.Item4);
  159. }
  160. }
  161. }
  162. return (MapperConfiguration<TDest, TSource>)map;
  163. }
  164. /// <summary>
  165. /// 是否使用服务注入
  166. /// </summary>
  167. public MapperConfiguration<TSource, TDest> ConstructUsingServiceLocator()
  168. {
  169. UseServiceLocator = true;
  170. return this;
  171. }
  172. }
  173. }