Stashbox by Peter Csajtai

<PackageReference Include="Stashbox" Version="3.1.1" />

 ExpressionExtensions

public static class 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); } } }