using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Luticate2.Auth.Dbo; using Luticate2.Auth.Dbo.Result; namespace Luticate2.Auth.Business { public static class LuExpressionUtils { public static Expression GetFromConvert(Expression> exp) { Expression operand; if ((exp.Body.NodeType == ExpressionType.Convert || exp.Body.NodeType == ExpressionType.ConvertChecked) && exp.Body is UnaryExpression) { operand = ((UnaryExpression) exp.Body).Operand; } else { operand = exp.Body; } return operand; } public static Expression> AddConvert(Expression> exp) { var converted = Expression.Convert(exp, typeof(object)); var expLambda = Expression.Lambda>(converted, exp.Parameters); return expLambda; } public static LuResult SetValueFromExpression(Expression> property, TDbo dboTo, TProperty value) { var memberInfo = GetSingleMemberFromExpression(property); if (memberInfo != null) { switch (memberInfo.MemberType) { case MemberTypes.Field: ((FieldInfo) memberInfo).SetValue(dboTo, value); return LuResult.Ok(value); case MemberTypes.Property: ((PropertyInfo) memberInfo).SetValue(dboTo, value); return LuResult.Ok(value); default: return LuResult.Error(LuStatus.InternalError.ToInt(), $"Bad MemberType: {memberInfo.MemberType}"); } } return LuResult.Error(LuStatus.InternalError.ToInt(), "Bad member expression"); } public static LuResult GetValueFromExpression(Expression> property, TDbo dboTo) { var memberInfo = GetSingleMemberFromExpression(property); if (memberInfo != null) { TProperty value; switch (memberInfo.MemberType) { case MemberTypes.Field: value = (TProperty) ((FieldInfo) memberInfo).GetValue(dboTo); return LuResult.Ok(value); case MemberTypes.Property: value = (TProperty) ((PropertyInfo) memberInfo).GetValue(dboTo); return LuResult.Ok(value); default: return LuResult.Error(LuStatus.InternalError.ToInt(), $"Bad MemberType: {memberInfo.MemberType}"); } } return LuResult.Error(LuStatus.InternalError.ToInt(), "Bad member expression"); } public static MemberInfo GetSingleMemberFromExpression(Expression> property) { var memberExpression = GetFromConvert(property) as MemberExpression; if (memberExpression != null && memberExpression.Expression == property.Parameters.First()) { return memberExpression.Member; } return null; } private static bool GetMembersFromExpression( Expression> property, IList memberInfos) { MemberExpression memberExpression; if ((property.Body.NodeType == ExpressionType.Convert || property.Body.NodeType == ExpressionType.ConvertChecked) && property.Body is UnaryExpression) { memberExpression = ((UnaryExpression) property.Body).Operand as MemberExpression; } else { memberExpression = property.Body as MemberExpression; } if (memberExpression != null) { if (memberExpression.Expression == property.Parameters.First()) { memberInfos.Add(memberExpression.Member); return true; } else if (memberExpression.Expression is MemberExpression) { var exp = Expression.Lambda>(memberExpression.Expression, property.Parameters); var res = GetMembersFromExpression(exp, memberInfos); if (res) { memberInfos.Add(memberExpression.Member); } return res; } } return false; } public static IList GetMembersFromExpression(Expression> property) { var list = new List(); if (GetMembersFromExpression(property, list)) { return list; } return null; } } }