using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace EasyDevCore.Common { /// /// /// public static class ExpressionHelper { /// /// Gets the property. /// /// The type of the entity. /// The type of the property. /// The expression. /// /// public static PropertyInfo GetProperty(Expression> expression) { var member = GetMemberExpression(expression).Member; var property = member as PropertyInfo; if (property == null) { throw new InvalidOperationException(string.Format("Member with Name '{0}' is not a property.", member.Name)); } return property; } /// /// Gets the member expression. /// /// The type of the entity. /// The type of the property. /// The expression. /// /// Not a member access - expression private static MemberExpression GetMemberExpression(Expression> expression) { MemberExpression memberExpression = null; if (expression.Body.NodeType == ExpressionType.Convert) { var body = (UnaryExpression)expression.Body; memberExpression = body.Operand as MemberExpression; } else if (expression.Body.NodeType == ExpressionType.MemberAccess) { memberExpression = expression.Body as MemberExpression; } if (memberExpression == null) { throw new ArgumentException("Not a member access", "expression"); } return memberExpression; } /// /// Creates the setter. /// /// The type of the entity. /// The type of the property. /// The property. /// public static Action CreateSetter(Expression> property) { PropertyInfo propertyInfo = ExpressionHelper.GetProperty(property); ParameterExpression instance = Expression.Parameter(typeof(TEntity), "instance"); ParameterExpression parameter = Expression.Parameter(typeof(TProperty), "param"); var body = Expression.Call(instance, propertyInfo.GetSetMethod(), parameter); var parameters = new ParameterExpression[] { instance, parameter }; return Expression.Lambda>(body, parameters).Compile(); } /// /// Creates the getter. /// /// The type of the entity. /// The type of the property. /// The property. /// public static Func CreateGetter(Expression> property) { PropertyInfo propertyInfo = ExpressionHelper.GetProperty(property); ParameterExpression instance = Expression.Parameter(typeof(TEntity), "instance"); var body = Expression.Call(instance, propertyInfo.GetGetMethod()); var parameters = new ParameterExpression[] { instance }; return Expression.Lambda>(body, parameters).Compile(); } /// /// Creates the default constructor. /// /// The type of the entity. /// public static Func CreateDefaultConstructor() { var body = Expression.New(typeof(TEntity)); var lambda = Expression.Lambda>(body); return lambda.Compile(); } /// /// Gets the property getter. /// /// The type of the object. /// The type of the property. /// Name of the property. /// public static Func GetPropGetter(string propertyName) { ParameterExpression paramExpression = Expression.Parameter(typeof(TObject), "value"); Expression propertyGetterExpression = Expression.Property(paramExpression, propertyName); Func result = Expression.Lambda>(propertyGetterExpression, paramExpression).Compile(); return result; } /// /// Gets the property setter. /// /// The type of the object. /// The type of the property. /// Name of the property. /// public static Action GetPropSetter(string propertyName) { ParameterExpression paramExpression = Expression.Parameter(typeof(TObject)); ParameterExpression paramExpression2 = Expression.Parameter(typeof(TProperty), propertyName); MemberExpression propertyGetterExpression = Expression.Property(paramExpression, propertyName); Action result = Expression.Lambda> ( Expression.Assign(propertyGetterExpression, paramExpression2), paramExpression, paramExpression2 ).Compile(); return result; } /// /// Gets the value getter. /// var getter = property.GetValueGetter<ReflectedType>(); /// /// /// The property information. /// /// public static Func GetValueGetter(this PropertyInfo propertyInfo) { if (typeof(T) != propertyInfo.DeclaringType) { throw new ArgumentException(); } var instance = Expression.Parameter(propertyInfo.DeclaringType, "i"); var property = Expression.Property(instance, propertyInfo); var convert = Expression.TypeAs(property, typeof(object)); return (Func)Expression.Lambda(convert, instance).Compile(); } /// /// Gets the value setter. /// var setter = property.GetValueSetter<ReflectedType>(); /// /// /// The property information. /// /// public static Action GetValueSetter(this PropertyInfo propertyInfo) { if (typeof(T) != propertyInfo.DeclaringType) { throw new ArgumentException(); } var instance = Expression.Parameter(propertyInfo.DeclaringType, "i"); var argument = Expression.Parameter(typeof(object), "a"); var setterCall = Expression.Call( instance, propertyInfo.GetSetMethod(), Expression.Convert(argument, propertyInfo.PropertyType)); return (Action)Expression.Lambda(setterCall, instance, argument).Compile(); } } }