public async Task <TSuccessResult> ProcessAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command)
            where TCommand : IAsyncCommand
        {
            TSuccessResult result;

            try
            {
                var executingPipeline = _commandsBuilder.ExecutingPipelines.Reverse() // TODO: always reversing?
                                        .Aggregate((ExecutingPipeline) new FinalExecutingPipeline(this),
                                                   (current, executingPipelineType) => (ExecutingPipeline)_dependencyService.Resolve(executingPipelineType, typeof(ExecutingPipeline), current));

                result = await executingPipeline.ExecutingAsync(command).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                var exceptionPipeline = _commandsBuilder.ExceptionPipelines.Reverse()
                                        .Aggregate((ExceptionPipeline) new FinalExceptionPipeline(),
                                                   (current, exceptionPipelineType) => (ExceptionPipeline)_dependencyService.Resolve(exceptionPipelineType, typeof(ExceptionPipeline), current));

                var newResult = await exceptionPipeline.ExceptionAsync(command, exception).ConfigureAwait(false);

                if (newResult is Exception newException)
                {
                    ExceptionDispatchInfo.Capture(newException).Throw();
                }

                return((TSuccessResult)newResult); // TODO: I don't think this should go back into the outgoing...
            }

            var executedPipeline = _commandsBuilder.ExecutedPipelines.Reverse()
                                   .Aggregate((ExecutedPipeline) new FinalExecutedPipeline(),
                                              (current, executedPipelineType) => (ExecutedPipeline)_dependencyService.Resolve(executedPipelineType, typeof(ExecutedPipeline), current));

            return(await executedPipeline.ExecutedAsync(command, result).ConfigureAwait(false));
        }
Example #2
0
 public async Task <TSuccessResult> ProcessAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command)
     where TCommand : IAsyncCommand
 {
     using (var internalCommandProcessor =
                new InternalCommandProcessor(_commandsBuilder, _lifetimeScopeService, command))
     {
         return(await internalCommandProcessor.ProcessAsync(command).ConfigureAwait(false));
     }
 }
        public void WhenNotFromAdoReturnsEmptyList()
        {
            ISuccessResult <WorkItemLink[]> result = (ISuccessResult <WorkItemLink[]>)CreateWorkItemLinkMapper().Map(new OctopusBuildInformation
            {
                BuildEnvironment = "Something",
                BuildUrl         = "http://redstoneblock/DefaultCollection/Deployable/_build/results?buildId=24"
            });

            Assert.IsEmpty(result.Value);
        }
        public ResultRegisterProcessor(ISuccessResult <TCommand, TSuccessResult> command, IReadOnlyDictionary <Type, Func <object, TReturn> > defaultResultParsers,
                                       ICommandProcessor commandProcessor)
        {
            Contract.Requires(command != null);
            Contract.Requires(defaultResultParsers != null);
            Contract.Requires(commandProcessor != null);

            _command = command;
            _defaultResultParsers = defaultResultParsers;
            _commandProcessor     = commandProcessor;
        }
Example #5
0
        public async Task <TSuccessResult> ProcessAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command)
            where TCommand : IAsyncCommand
        {
            var resultTaskCompletionSource = new TaskCompletionSource <TSuccessResult>();

            // TODO: timeout
            var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(15));

            cancellationTokenSource.Token.Register(() => resultTaskCompletionSource.TrySetException(new Exception("30b1ddaa-21d9-452d-8c32-faf070dc7c8c")));

            var commandTransport = new CommandContainer
            {
                Id      = Guid.NewGuid().ToString(), // TODO: could i do a string ID which i pass in and then stop duplicates. For example the ID of the object to be created in the db
                Command = command
            };

            await _commandTransportClient.ListenAsync <TSuccessResult>(commandTransport.Id, resultTransport =>
            {
                if (resultTransport.Success)
                {
                    resultTaskCompletionSource.SetResult(resultTransport.Result);
                }
                else if (!resultTransport.Success)
                {
                    resultTaskCompletionSource.SetException(resultTransport.Exception);
                }
                else
                {
                    throw new NotImplementedException();
                }

                return(Task.CompletedTask);
            }).ConfigureAwait(false);

            await _commandTransportClient.SendAsync(commandTransport).ConfigureAwait(false);

            return(await resultTaskCompletionSource.Task.ConfigureAwait(false));
        }
 public async Task <CommandProcessorSuccessResult <TSuccessResult> > ProcessResultAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command)
     where TCommand : IAsyncCommand
 {
     try
     {
         return(new CommandProcessorSuccessResult <TSuccessResult>(await ProcessAsync(command).ConfigureAwait(false)));
     }
     catch (Exception exception)
     {
         return(new CommandProcessorSuccessResult <TSuccessResult>(exception));
     }
 }
Example #7
0
 public override Task <TSuccessResult> ExecutedAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command, TSuccessResult result)
 {
     Console.WriteLine("ExecutedAsync");
     return(base.ExecutedAsync(command, result));
 }
 public override Task <object> ExceptionAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command, Exception exception)
 {
     return(Task.FromResult((object)exception));
 }
 public virtual Task <object> ExceptionAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command, Exception exception)
     where TCommand : IAsyncCommand
 {
     return(_nextExceptionPipeline.ExceptionAsync(command, exception));
 }
Example #10
0
 // can i make one which only returns the success
 public ResultRegisterProcessor <TCommand, TSuccessResult, TReturn> For <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command)
     where TCommand : IAsyncCommand
 {
     return(new ResultRegisterProcessor <TCommand, TSuccessResult, TReturn>
                (command, _resultParsers, _commandProcessor));
 }
 public override Task <TSuccessResult> ExecutingAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command)
 {
     return(_commandProcessor.ExecuteAsync(command));
 }
 public virtual Task <TSuccessResult> ExecutingAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command)
     where TCommand : IAsyncCommand
 {
     return(_nextExecutingPipeline.ExecutingAsync(command));
 }
Example #13
0
 public override Task <TSuccessResult> ExecutedAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command, TSuccessResult result)
 {
     return(Task.FromResult(result));
 }
Example #14
0
 public static TResult Success <TCommand, TResult>(this ISuccessResult <TCommand, TResult> result)
     where TCommand : IAsyncCommand
 {
     return(default);
Example #15
0
 public Task <TSuccessResult> ProcessAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command) where TCommand : IAsyncCommand
 {
     throw new NotImplementedException();
 }
        internal async Task <TSuccessResult> ExecuteAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command)
            where TCommand : IAsyncCommand
        {
            var isInitialCommand = command == _initialCommand;

            var allClassTypes = GetAllConcreteClassTypes(typeof(TCommand));

            // TODO: only create with IAsyncCommand, if none then throw a handler not found exception.. an analyzer could check this
            var firstRegisteredClassType = allClassTypes.First(t => _dependencyService.IsRegistered(typeof(IAsyncCommandHandler <,>).MakeGenericType(t, typeof(TSuccessResult))));

            var handlerType = typeof(IAsyncCommandHandler <,>).MakeGenericType(firstRegisteredClassType, typeof(TSuccessResult));
            var handler     = _dependencyService.Resolve(handlerType);

            var pipelines = _commandsBuilder.Pipelines.Select(p => (Pipeline)_dependencyService.Resolve(p)).ToList();

            // run executing pipeline and notification
            foreach (var pipeline in pipelines)
            {
                if (pipeline.GetType().GetTypeInfo().GetCustomAttribute <SingletonAttribute>() == null || isInitialCommand)
                {
                    await pipeline.ExecutingAsync(command).ConfigureAwait(false);
                }
            }

            if (_commandsBuilder.ExecutingNotifications.TryGetValue(typeof(TCommand), out var executingNotifications))
            {
                foreach (var executingNotification in executingNotifications)
                {
                    // TODO: can this be done a better way?
                    await((Task)typeof(IExecutingNotification <>).MakeGenericType(typeof(TCommand))
                          .GetTypeInfo().GetMethod("OnExecutingAsync", new[] { command.GetType() })
                          .Invoke(_dependencyService.Resolve(executingNotification), new object[] { command })).ConfigureAwait(false);
                }
            }

            Task <TSuccessResult> task = null;

            try
            {
                task = (Task <TSuccessResult>)handlerType.GetTypeInfo().GetMethod("ExecuteAsync", new[] { command.GetType() }).Invoke(handler, new object[] { command });

                var result = await task.ConfigureAwait(false);

                if (_commandsBuilder.ExecutedNotifications.TryGetValue(typeof(TCommand), out var executedNotifications))
                {
                    foreach (var executedNotification in executedNotifications)
                    {
                        await((Task)typeof(IExecutedNotification <,>).MakeGenericType(typeof(TCommand), typeof(TSuccessResult))
                              .GetTypeInfo().GetMethod("OnExecutedAsync", new[] { command.GetType(), typeof(TSuccessResult) })
                              .Invoke(_dependencyService.Resolve(executedNotification), new object[] { command, result })).ConfigureAwait(false);
                    }
                }

                pipelines.Reverse();
                foreach (var pipeline in pipelines)
                {
                    if (pipeline.GetType().GetTypeInfo().GetCustomAttribute <SingletonAttribute>() == null || isInitialCommand)
                    {
                        await pipeline.ExecutedAsync(command, result).ConfigureAwait(false);
                    }
                }
            }
            catch (Exception exception)
            {
                // if the command was not async, we will need to get the inner exception
                if (exception is TargetInvocationException targetInvocationException)
                {
                    exception = targetInvocationException.InnerException;
                }

                // run exception notification and pipeline
                if (_commandsBuilder.ExceptionNotifications.TryGetValue(typeof(TCommand), out var exceptionNotifications))
                {
                    foreach (var exceptionNotification in exceptionNotifications)
                    {
                        await((Task)typeof(IExceptionNotification <>).MakeGenericType(typeof(TCommand))
                              .GetTypeInfo().GetMethod("OnExceptionAsync", new[] { command.GetType(), typeof(Exception) })
                              .Invoke(_dependencyService.Resolve(exceptionNotification), new object[] { command, exception })).ConfigureAwait(false);
                    }
                }

                pipelines.Reverse();
                foreach (var pipeline in pipelines)
                {
                    if (pipeline.GetType().GetTypeInfo().GetCustomAttribute <SingletonAttribute>() == null || isInitialCommand)
                    {
                        await pipeline.ExceptionAsync(command, exception).ConfigureAwait(false);
                    }
                }

                ExceptionDispatchInfo.Capture(exception).Throw();
            }

            return(await task.ConfigureAwait(false));
        }
 public override Task <object> ExceptionAsync <TCommand, TSuccessResult>(ISuccessResult <TCommand, TSuccessResult> command, Exception exception)
 {
     Console.WriteLine("ExceptionAsync");
     return(base.ExceptionAsync(command, exception));
 }