ExpressionExtensions
Holds the Expression extension methods.
using Stashbox;
using Stashbox.Configuration;
using Stashbox.Expressions.Compile;
using Stashbox.Resolution;
using System.Collections.Generic;
using System.Reflection;
namespace System.Linq.Expressions
{
public static class ExpressionExtensions
{
public static Func<IResolutionScope, object> CompileDelegate(this Expression expression, ResolutionContext resolutionContext, ContainerConfiguration containerConfiguration)
{
if (expression.NodeType == ExpressionType.Constant) {
object instance = ((ConstantExpression)expression).Value;
return (IResolutionScope scope) => instance;
}
if (!resolutionContext.DefinedVariables.IsEmpty) {
resolutionContext.SingleInstructions.Add(expression);
expression = Expression.Block(resolutionContext.DefinedVariables.WalkOnValues(), resolutionContext.SingleInstructions);
}
if (containerConfiguration.ExternalExpressionCompiler != null)
return (Func<IResolutionScope, object>)containerConfiguration.ExternalExpressionCompiler(expression.AsLambda(resolutionContext.CurrentScopeParameter));
Delegate resultDelegate = default(Delegate);
if (!expression.TryEmit(out resultDelegate, typeof(Func<IResolutionScope, object>), typeof(object), resolutionContext.CurrentScopeParameter))
resultDelegate = expression.AsLambda(resolutionContext.CurrentScopeParameter).Compile();
return (Func<IResolutionScope, object>)resultDelegate;
}
public static Delegate CompileDelegate(this LambdaExpression expression)
{
if (!expression.TryEmit(out Delegate resultDelegate))
throw new InvalidOperationException("Could not compile the given expression!");
return resultDelegate;
}
public static Func<IResolutionScope, Delegate> CompileDynamicDelegate(this Expression expression, ResolutionContext resolutionContext, ContainerConfiguration containerConfiguration)
{
if (!resolutionContext.DefinedVariables.IsEmpty) {
resolutionContext.SingleInstructions.Add(expression);
expression = Expression.Block(resolutionContext.DefinedVariables.WalkOnValues(), resolutionContext.SingleInstructions);
}
if (containerConfiguration.ExternalExpressionCompiler != null)
return (Func<IResolutionScope, Delegate>)containerConfiguration.ExternalExpressionCompiler(expression.AsLambda(resolutionContext.CurrentScopeParameter));
Delegate resultDelegate = default(Delegate);
if (expression.TryEmit(out resultDelegate, typeof(Func<IResolutionScope, Delegate>), typeof(Delegate), resolutionContext.CurrentScopeParameter))
resultDelegate = expression.AsLambda<Func<IResolutionScope, Delegate>>(new ParameterExpression[1] {
resolutionContext.CurrentScopeParameter
}).Compile();
return (Func<IResolutionScope, Delegate>)resultDelegate;
}
public static Func<T> CompileFunc<T>(this Expression<Func<T>> expression)
{
return (Func<T>)expression.CompileDelegate();
}
public static Func<T1, T> CompileFunc<T1, T>(this Expression<Func<T1, T>> expression)
{
return (Func<T1, T>)expression.CompileDelegate();
}
public static BinaryExpression AssignTo(this Expression left, Expression right)
{
return Expression.Assign(left, right);
}
public static MemberAssignment AssignTo(this MemberInfo memberInfo, Expression expression)
{
return Expression.Bind(memberInfo, expression);
}
public static ConstantExpression AsConstant(this object obj)
{
return Expression.Constant(obj);
}
public static ConstantExpression AsConstant(this object obj, Type type)
{
return Expression.Constant(obj, type);
}
public static DefaultExpression AsDefault(this Type type)
{
return Expression.Default(type);
}
public static BlockExpression AsBlock(this IEnumerable<Expression> expressions, params ParameterExpression[] variables)
{
return Expression.Block(variables, expressions);
}
public static LambdaExpression AsLambda(this Expression expression, params ParameterExpression[] parameters)
{
return Expression.Lambda(expression, parameters);
}
public static LambdaExpression AsLambda(this Expression expression, Type delegateType, IEnumerable<ParameterExpression> parameters)
{
return Expression.Lambda(delegateType, expression, parameters);
}
public static LambdaExpression AsLambda(this Expression expression, Type delegateType, params ParameterExpression[] parameters)
{
return Expression.Lambda(delegateType, expression, parameters);
}
public static LambdaExpression AsLambda(this Expression expression, IEnumerable<ParameterExpression> parameters)
{
return Expression.Lambda(expression, parameters);
}
public static Expression<TDelegate> AsLambda<TDelegate>(this Expression expression, params ParameterExpression[] parameters)
{
return Expression.Lambda<TDelegate>(expression, parameters);
}
public static ParameterExpression AsVariable(this Type type, string name = null)
{
return Expression.Variable(type, name);
}
public static ParameterExpression AsParameter(this Type type, string name = null)
{
return Expression.Parameter(type, name);
}
public static MethodCallExpression CallStaticMethod(this MethodInfo methodInfo, params Expression[] parameters)
{
return Expression.Call(methodInfo, parameters);
}
public static MethodCallExpression CallMethod(this Expression target, MethodInfo methodInfo, params Expression[] parameters)
{
return Expression.Call(target, methodInfo, parameters);
}
public static MethodCallExpression CallMethod(this Expression target, MethodInfo methodInfo, IEnumerable<Expression> parameters)
{
return Expression.Call(target, methodInfo, parameters);
}
public static MethodCallExpression CallMethod(this MethodInfo methodInfo, Expression target, params Expression[] parameters)
{
return target.CallMethod(methodInfo, parameters);
}
public static Expression ConvertTo(this Expression expression, Type type)
{
return Expression.Convert(expression, type);
}
public static InvocationExpression InvokeLambda(this LambdaExpression expression, params Expression[] parameters)
{
return Expression.Invoke(expression, parameters);
}
public static InvocationExpression InvokeDelegate(this Delegate delegate, params Expression[] parameters)
{
return Expression.Invoke(delegate.AsConstant(), parameters);
}
public static NewExpression MakeNew(this ConstructorInfo constructor, IEnumerable<Expression> arguments)
{
return Expression.New(constructor, arguments);
}
public static NewExpression MakeNew(this ConstructorInfo constructor, params Expression[] arguments)
{
return Expression.New(constructor, arguments);
}
public static MemberExpression Member(this Expression expression, MemberInfo memberInfo)
{
PropertyInfo propertyInfo = memberInfo as PropertyInfo;
if ((object)propertyInfo == null)
return Expression.Field(expression, memberInfo as FieldInfo);
return Expression.Property(expression, propertyInfo);
}
public static MemberExpression Prop(this Expression expression, PropertyInfo propertyInfo)
{
return Expression.Property(expression, propertyInfo);
}
public static MemberExpression Access(this PropertyInfo propertyInfo, Expression expression)
{
return Expression.Property(expression, propertyInfo);
}
public static MemberInitExpression InitMembers(this Expression expression, IEnumerable<MemberBinding> bindings)
{
return Expression.MemberInit((NewExpression)expression, bindings);
}
public static NewArrayExpression InitNewArray(this Type type, params Expression[] initializerExpressions)
{
return Expression.NewArrayInit(type, initializerExpressions);
}
public static NewArrayExpression InitNewArray(this Type type, IEnumerable<Expression> initializerExpressions)
{
return Expression.NewArrayInit(type, initializerExpressions);
}
}
}