Example #1
0
        private Task ExecuteStep(StepDescriptor step, IPipelineExecutionContext executionContext, CancellationToken cancellationToken, ExecuteStepDelegate @delegate, IPipelineBehavior[] behaviors)
        {
            var stepInstance = _factory(step.TypeInfo);

            executionContext.CurrentStep = stepInstance;

            Func <CancellationToken, Task> currentFunc = token => @delegate(stepInstance, executionContext, _namingStrategy, _unknownParameterBehavior, token);

            for (var i = behaviors.Length - 1; i >= 0; i--)
            {
                var behavior     = behaviors[i];
                var previousFunc = currentFunc;
                currentFunc = token => behavior.Handle(executionContext, cancellationToken, previousFunc);
            }

            return(currentFunc(cancellationToken));
        }
        internal static ExecuteStepDelegate CreateDelegate(this StepDescriptor step)
        {
            var arguments = new List <Expression>();
            var executionContextParameter         = Expression.Parameter(typeof(IPipelineExecutionContext));
            var cancellationTokenParameter        = Expression.Parameter(typeof(CancellationToken));
            var namingStrategyParameter           = Expression.Parameter(typeof(INamingStrategy));
            var unknownParameterBehaviorParameter = Expression.Parameter(typeof(IUnknownParameterBehavior));
            var instanceParameter = Expression.Parameter(typeof(object));

            for (var i = 0; i < step.Parameters.Length; i++)
            {
                var(parameterName, parameterType) = step.Parameters[i];
                if (parameterType == typeof(IPipelineExecutionContext))
                {
                    arguments.Add(executionContextParameter);
                }
                else if (parameterType == typeof(CancellationToken))
                {
                    arguments.Add(cancellationTokenParameter);
                }
                else
                {
                    var allNames         = Expression.Property(executionContextParameter, "Names");
                    var getParameterName = Expression.Call(namingStrategyParameter, "FindMatch", new Type[0], Expression.Constant(parameterName), allNames);
                    var body             = Expression.Call(executionContextParameter, "Get", new[] { parameterType }, getParameterName);

                    var handleUnkownParameter = Expression.Call(unknownParameterBehaviorParameter, "Handle", new Type[] { parameterType }, Expression.Constant(parameterName));
                    var @catch = Expression.Catch(typeof(ArgumentException), handleUnkownParameter);
                    var @try   = Expression.TryCatch(body, @catch);
                    arguments.Add(@try);
                }
            }

            var methodCall = Expression.Call(Expression.Convert(instanceParameter, step.TypeInfo), step.Method, arguments);

            if (!typeof(Task).IsAssignableFrom(step.Method.ReturnType))
            {
                var result  = Expression.Constant(Task.CompletedTask);
                var wrapper = Expression.Block(typeof(Task), methodCall, result);
                return(Expression.Lambda <ExecuteStepDelegate>(wrapper, instanceParameter, executionContextParameter, namingStrategyParameter,
                                                               unknownParameterBehaviorParameter, cancellationTokenParameter).Compile());
            }

            return(Expression.Lambda <ExecuteStepDelegate>(methodCall, instanceParameter, executionContextParameter, namingStrategyParameter,
                                                           unknownParameterBehaviorParameter, cancellationTokenParameter).Compile());
        }