Beispiel #1
0
        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));
        }
Beispiel #2
0
        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);
        }
Beispiel #5
0
        /// <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());
        }