Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

LuExpressionUtils.cs 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Reflection;
  6. using Luticate2.Auth.Utils.Dbo;
  7. using Luticate2.Auth.Utils.Dbo.Result;
  8. namespace Luticate2.Auth.Utils.Business.Utils
  9. {
  10. public static class LuExpressionUtils
  11. {
  12. public static Expression GetFromConvert(Expression exp)
  13. {
  14. if (exp is LambdaExpression lambdaExpression)
  15. {
  16. return GetFromConvert(lambdaExpression);
  17. }
  18. if ((exp.NodeType == ExpressionType.Convert ||
  19. exp.NodeType == ExpressionType.ConvertChecked)
  20. && exp is UnaryExpression)
  21. {
  22. return ((UnaryExpression) exp).Operand;
  23. }
  24. else
  25. {
  26. return exp;
  27. }
  28. }
  29. public static LambdaExpression GetFromConvert(LambdaExpression exp)
  30. {
  31. var body = GetFromConvert(exp.Body);
  32. var lambda = Expression.Lambda(body, exp.Parameters);
  33. return lambda;
  34. }
  35. public static Expression<Func<TType1, TType3>> AddConvert<TType1, TType2, TType3>(Expression<Func<TType1, TType2>> exp)
  36. {
  37. var converted = Expression.Convert(exp.Body, typeof(TType3));
  38. var expLambda = Expression.Lambda<Func<TType1, TType3>>(converted, exp.Parameters);
  39. return expLambda;
  40. }
  41. public static LuResult<TProperty> SetValueFromExpression<TDbo, TProperty>(Expression<Func<TDbo, TProperty>> property,
  42. TDbo dstObj, TProperty value)
  43. {
  44. var memberInfo = GetSingleMemberFromExpression(property);
  45. if (memberInfo != null)
  46. {
  47. return SetValueFromMember(memberInfo, dstObj, value);
  48. }
  49. return LuResult<TProperty>.Error(LuStatus.InternalError.ToInt(), "Bad member expression");
  50. }
  51. public static LuResult<TProperty> SetValueFromMember<TDbo, TProperty>(MemberInfo memberInfo,
  52. TDbo dstObj, TProperty value)
  53. {
  54. switch (memberInfo.MemberType)
  55. {
  56. case MemberTypes.Field:
  57. ((FieldInfo) memberInfo).SetValue(dstObj, value);
  58. return LuResult<TProperty>.Ok(value);
  59. case MemberTypes.Property:
  60. ((PropertyInfo) memberInfo).SetValue(dstObj, value);
  61. return LuResult<TProperty>.Ok(value);
  62. default:
  63. return LuResult<TProperty>.Error(LuStatus.InternalError.ToInt(),
  64. $"Bad MemberType: {memberInfo.MemberType}");
  65. }
  66. }
  67. public static LuResult<TProperty> GetValueFromExpression<TDbo, TProperty>(Expression<Func<TDbo, TProperty>> property,
  68. TDbo dboTo)
  69. {
  70. var memberInfo = GetSingleMemberFromExpression(property);
  71. if (memberInfo != null)
  72. {
  73. TProperty value;
  74. switch (memberInfo.MemberType)
  75. {
  76. case MemberTypes.Field:
  77. value = (TProperty) ((FieldInfo) memberInfo).GetValue(dboTo);
  78. return LuResult<TProperty>.Ok(value);
  79. case MemberTypes.Property:
  80. value = (TProperty) ((PropertyInfo) memberInfo).GetValue(dboTo);
  81. return LuResult<TProperty>.Ok(value);
  82. default:
  83. return LuResult<TProperty>.Error(LuStatus.InternalError.ToInt(),
  84. $"Bad MemberType: {memberInfo.MemberType}");
  85. }
  86. }
  87. return LuResult<TProperty>.Error(LuStatus.InternalError.ToInt(), "Bad member expression");
  88. }
  89. public static MemberInfo GetSingleMemberFromExpression(LambdaExpression property)
  90. {
  91. if (GetFromConvert(property.Body) is MemberExpression memberExpression &&
  92. (memberExpression.Expression == property.Parameters.First() ||
  93. (memberExpression.Expression == null && memberExpression.Member.DeclaringType == property.Parameters.First().Type)))
  94. {
  95. return memberExpression.Member;
  96. }
  97. return null;
  98. }
  99. public static MethodInfo GetSingleMethodFromExpression(LambdaExpression method)
  100. {
  101. // TODO check if something like methodCallExpression.Method.DeclaringType == method.Parameters.First().Type is usefull/required (static/extension methods)
  102. if (GetFromConvert(method.Body) is MethodCallExpression methodCallExpression &&
  103. (methodCallExpression.Object == method.Parameters.First() || methodCallExpression.Object == null))
  104. {
  105. return methodCallExpression.Method;
  106. }
  107. return null;
  108. }
  109. private static bool GetMembersFromExpression<TTypeTo, TProperty>(
  110. Expression<Func<TTypeTo, TProperty>> property, IList<MemberInfo> memberInfos)
  111. {
  112. MemberExpression memberExpression;
  113. if ((property.Body.NodeType == ExpressionType.Convert ||
  114. property.Body.NodeType == ExpressionType.ConvertChecked)
  115. && property.Body is UnaryExpression)
  116. {
  117. memberExpression = ((UnaryExpression) property.Body).Operand as MemberExpression;
  118. }
  119. else
  120. {
  121. memberExpression = property.Body as MemberExpression;
  122. }
  123. if (memberExpression != null)
  124. {
  125. if (memberExpression.Expression == property.Parameters.First())
  126. {
  127. memberInfos.Add(memberExpression.Member);
  128. return true;
  129. }
  130. else if (memberExpression.Expression is MemberExpression)
  131. {
  132. var exp = Expression.Lambda<Func<TTypeTo, object>>(memberExpression.Expression, property.Parameters);
  133. var res = GetMembersFromExpression(exp, memberInfos);
  134. if (res)
  135. {
  136. memberInfos.Add(memberExpression.Member);
  137. }
  138. return res;
  139. }
  140. }
  141. return false;
  142. }
  143. public static IList<MemberInfo> GetMembersFromExpression<TTypeTo, TProperty>(Expression<Func<TTypeTo, TProperty>> property)
  144. {
  145. var list = new List<MemberInfo>();
  146. if (GetMembersFromExpression(property, list))
  147. {
  148. return list;
  149. }
  150. return null;
  151. }
  152. }
  153. }