Example #1
0
        /// <summary>
        /// This method executes the <see cref="IPipelineOperation{TContext}.Execute(TContext)"/> method of the specified
        /// <see cref="IPipelineOperation{TContext}"/> object passing it the <see cref="TContext"/> from the method parameter.
        /// </summary>
        /// <typeparam name="TOperation">The object that will be used to process the <see cref="TContext"/> object</typeparam>
        /// <param name="context">The state object that will be acted upon</param>
        /// <returns><see cref="IPipelineCoordinator{TContext}"/> for dot chaining</returns>
        public virtual IPipelineCoordinator <TContext> Execute <TOperation>(TContext context) where TOperation : IPipelineOperation <TContext>
        {
            if (context == null)
            {
                throw new ArgumentException($"Parameter {typeof(TContext).Name} {nameof(context)} cannot be null", nameof(context));
            }

            var opType = typeof(TOperation);

            if (context.EndProcessing)
            {
                context.ResultMessages.Add($"[{opType.Name}] Not Executed. A previous Operation terminated the operation pipeline.");
                return(this);
            }

            var operation = Operations[opType];

            try
            {
                CheckDependencies(operation);
            }
            catch (OperationDependencyNotExecutedException ex)
            {
                context.EndProcessing = true;
                context.Exceptions.Add(ex);
                return(this);
            }

            try
            {
                operation.Execute(context);
            }
            catch (Exception ex)
            {
                context.Successful = false;
                context.Exceptions.Add(ex);

                if (ex is OperationExecutionException && !OperationsExecuted.Contains(opType))
                {
                    OperationsExecuted.Add(opType);
                }

                return(this);
            }

            if (!OperationsExecuted.Contains(opType))
            {
                OperationsExecuted.Add(opType);
            }

            return(this);
        }
Example #2
0
 protected virtual void CheckDependencies(IPipelineOperation <TContext> operation)
 {
     operation
     .Dependencies
     .ToList()
     .ForEach(d =>
     {
         if (!OperationsExecuted.Contains(d))
         {
             var operationName  = operation.GetType().Name;
             var dependencyName = d.Name;
             var message        = $"The {operationName} operation could not execute because it requires that the {dependencyName} operation be executed before it";
             throw new OperationDependencyNotExecutedException(message);
         }
     });
 }
Example #3
0
        /// <summary>
        /// Adds the object specified by the <typeparamref name="TAsyncOperation"/> generic type to the <see cref="OperationTasks"/>
        /// collection to be awaited later asynchronously by one of the <see cref="WhenAll"/> methods
        /// </summary>
        /// <typeparam name="TAsyncOperation">The type of async operation that implements <see cref="IPipelineOperationAsync{TContext}"/></typeparam>
        /// <param name="context">The state object that will be acted upon</param>
        /// <returns><see cref="IPipelineCoordinator{TContext}"/> for dot chaining</returns>
        public virtual IPipelineCoordinator <TContext> AddAsyncOperation <TAsyncOperation>(TContext context) where TAsyncOperation : IPipelineOperationAsync <TContext>
        {
            if (context == null)
            {
                throw new ArgumentException($"Parameter {typeof(TContext).Name} {nameof(context)} cannot be null", nameof(context));
            }

            var opType = typeof(TAsyncOperation);

            if (context.EndProcessing)
            {
                context.ResultMessages.Add($"[{opType.Name}] Not Executed. A previous Operation terminated the operation pipeline.");
                return(this);
            }

            var operation = AsyncOperations[opType];

            try
            {
                CheckDependencies(operation);
            }
            catch (OperationDependencyNotExecutedException ex)
            {
                context.EndProcessing = true;
                context.Exceptions.Add(ex);
                return(this);
            }

            operation.Context = context;

            OperationTasks.Add(

                operation

                .ExecuteAsync()

                .ContinueWith(
                    (task) =>
            {
                try
                {
                    operation.CompletedTaskCallback(task);

                    if (!OperationsExecuted.Contains(opType))
                    {
                        OperationsExecuted.Add(opType);
                    }
                }
                catch (Exception ex)
                {
                    context.Successful = false;
                    context.Exceptions.Add(ex);

                    if (ex is OperationExecutionException && !OperationsExecuted.Contains(opType))
                    {
                        OperationsExecuted.Add(opType);
                    }
                }
            },
                    TaskContinuationOptions.OnlyOnRanToCompletion
                    )

                .ContinueWith(
                    (task) =>
            {
                context.Successful = false;
                context.Exceptions.Add(task.Exception);
            },
                    TaskContinuationOptions.OnlyOnFaulted
                    )

                );

            return(this);
        }
Example #4
0
        /// <summary>
        /// This method executes the <see cref="IPipelineOperationAsync{TContext}.ExecuteAsync"/> method of the specified
        /// <see cref="IPipelineOperationAsync{TContext}"/> object passing it the <see cref="TContext"/> from the method parameter
        /// from the <see cref="Context"/> property.
        /// </summary>
        /// <typeparam name="TAsyncOperation">The object that will be used to process the <see cref="TContext"/> object</typeparam>
        /// <param name="context">The state object that will be acted upon</param>
        /// <returns><see cref="IPipelineCoordinator{TContext}"/> for dot chaining</returns>
        public virtual IPipelineCoordinator <TContext> ExecuteAsync <TAsyncOperation>(TContext context) where TAsyncOperation : IPipelineOperationAsync <TContext>
        {
            if (context == null)
            {
                throw new ArgumentException($"Parameter {typeof(TContext).Name} {nameof(context)} cannot be null", nameof(context));
            }

            if (OperationTasks.Any())
            {
                throw new OperationExecutionException($"Cannot execute individual await Operation while other Operation Tasks are pending. Execute the {nameof(WhenAll)} method to clear the pending Operation Tasks first.");
            }

            var opType = typeof(TAsyncOperation);

            if (context.EndProcessing)
            {
                context.ResultMessages.Add($"[{opType.Name}] Not Executed. A previous Operation terminated the operation pipeline.");
                return(this);
            }

            var operation = AsyncOperations[opType];

            try
            {
                CheckDependencies(operation);
            }
            catch (OperationDependencyNotExecutedException ex)
            {
                context.EndProcessing = true;
                context.Exceptions.Add(ex);
                return(this);
            }

            operation.Context = context;

            var operationTask = operation
                                .ExecuteAsync()
                                .ContinueWith(task =>
            {
                try
                {
                    operation.CompletedTaskCallback(task);

                    if (!OperationsExecuted.Contains(opType))
                    {
                        OperationsExecuted.Add(opType);
                    }
                }
                catch (Exception ex)
                {
                    context.Successful = false;
                    context.Exceptions.Add(ex);

                    if (ex is OperationExecutionException && !OperationsExecuted.Contains(opType))
                    {
                        OperationsExecuted.Add(opType);
                    }
                }
            }, TaskContinuationOptions.OnlyOnRanToCompletion);

            try
            {
                operationTask.Wait();
            }
            catch (Exception ex)
            {
                context.Successful = false;
                context.Exceptions.Add(ex);

                if (ex is OperationExecutionException && !OperationsExecuted.Contains(opType))
                {
                    OperationsExecuted.Add(opType);
                }
            }

            return(this);
        }