private static ExpressionInfo <Func <int, int, int> > CreateSumExprInfo() { var aExp = ExpressionInfo.Parameter(typeof(int), "a"); var bExp = ExpressionInfo.Parameter(typeof(int), "b"); return(ExpressionInfo.Lambda <Func <int, int, int> >( ExpressionInfo.Add(aExp, bExp), aExp, bExp)); }
public void Can_sum_with_ExprInfo() { var a = ExpressionInfo.Parameter(typeof(int), "a"); var b = ExpressionInfo.Parameter(typeof(int), "b"); var expr = ExpressionInfo.Lambda <Func <int, int, int> >(ExpressionInfo.Add(a, b), a, b); var sumFunc = expr.CompileFast(true); Assert.IsNotNull(sumFunc); Assert.AreEqual(sumFunc(1, 3), 4); }
/// <code> /// rootContext /// => behavior1.Invoke(rootContext, /// context1 => behavior2.Invoke(context1, /// ... /// context{N} => behavior{N}.Invoke(context{N}, /// context{N+1} => TaskEx.Completed)) /// </code> public static Delegate CreatePipelineExecutionExpression(this IBehavior[] behaviors, List <Expression> expressions = null) { Delegate lambdaExpression = null; var behaviorCount = behaviors.Length - 1; // We start from the end of the list know the lambda expressions deeper in the call stack in advance for (var i = behaviorCount; i >= 0; i--) { var currentBehavior = behaviors[i]; var behaviorInterfaceType = currentBehavior.GetType().GetBehaviorInterface(); if (behaviorInterfaceType == null) { throw new InvalidOperationException("Behaviors must implement IBehavior<TInContext, TOutContext>"); } // Select the method on the type which was implemented from the behavior interface. var methodInfo = currentBehavior.GetType().GetInterfaceMap(behaviorInterfaceType).TargetMethods.FirstOrDefault(); if (methodInfo == null) { throw new InvalidOperationException("Behaviors must implement IBehavior<TInContext, TOutContext> and provide an invocation method."); } var genericArguments = behaviorInterfaceType.GetGenericArguments(); var inContextType = genericArguments[0]; var inContextParameter = ExpressionInfo.Parameter(inContextType, $"context{i}"); if (i == behaviorCount) { if (currentBehavior is IPipelineTerminator) { inContextType = typeof(PipelineTerminator <> .ITerminatingContext).MakeGenericType(inContextType); } var doneDelegate = CreateDoneDelegate(inContextType, i); lambdaExpression = CreateBehaviorCallDelegate(currentBehavior, methodInfo, inContextParameter, doneDelegate, expressions); continue; } lambdaExpression = CreateBehaviorCallDelegate(currentBehavior, methodInfo, inContextParameter, lambdaExpression, expressions); } return(lambdaExpression); }
/// <code> /// rootContext /// => behavior1.Invoke(rootContext, /// context1 => behavior2.Invoke(context1, /// ... /// context{N} => behavior{N}.Invoke(context{N}, /// context{N+1} => TaskEx.Completed)) /// </code> public static Delegate CreateFastPipelineExecutionExpression(this IBehavior[] behaviors, List <ExpressionInfo> expressions = null) { Delegate lambdaExpression = null; var length = behaviors.Length - 1; // We start from the end of the list know the lambda expressions deeper in the call stack in advance for (var i = length; i >= 0; i--) { var currentBehavior = behaviors[i]; var behaviorInterfaceType = currentBehavior.GetType().GetInterfaces().FirstOrDefault(t => t.GetGenericArguments().Length == 2 && t.FullName.StartsWith("NServiceBus.Pipeline.IBehavior")); if (behaviorInterfaceType == null) { throw new InvalidOperationException("Behaviors must implement IBehavior<TInContext, TOutContext>"); } var methodInfo = behaviorInterfaceType.GetMethods().FirstOrDefault(); if (methodInfo == null) { throw new InvalidOperationException("Behaviors must implement IBehavior<TInContext, TOutContext> and provide an invocation method."); } var genericArguments = behaviorInterfaceType.GetGenericArguments(); var inContextType = genericArguments[0]; var inContextParameter = ExpressionInfo.Parameter(inContextType, $"context{i}"); if (i == length) { if (currentBehavior is IPipelineTerminator) { inContextType = typeof(PipelineTerminator <> .ITerminatingContext).MakeGenericType(inContextType); } var doneDelegate = CreateDoneDelegate(inContextType, i); lambdaExpression = CreateBehaviorCallDelegate(currentBehavior, methodInfo, inContextParameter, doneDelegate, expressions); continue; } lambdaExpression = CreateBehaviorCallDelegate(currentBehavior, methodInfo, inContextParameter, lambdaExpression, expressions); } return(lambdaExpression); }
/// <code> /// context{i} => return TaskEx.CompletedTask; /// </code>> static Delegate CreateDoneDelegate(Type inContextType, int i) { var innerContextParam = ExpressionInfo.Parameter(inContextType, $"context{i + 1}"); return(ExpressionInfo.Lambda(ExpressionInfo.Constant(Task.CompletedTask), innerContextParam).CompileFast()); }