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();
}
}
}