private async Task <TResult> ExecuteCommandWithHandlers <TResult>(ICommand <TResult> command, ICommandDispatchContext dispatchContext, CancellationToken cancellationToken)
        {
            IReadOnlyCollection <IPrioritisedCommandHandler> handlers = _commandRegistry.GetPrioritisedCommandHandlers(command);

            if (handlers == null || handlers.Count == 0)
            {
                throw new MissingCommandHandlerRegistrationException(command.GetType(),
                                                                     "No command actors registered for execution of command");
            }
            TResult result = default(TResult);

            int handlerIndex = 0;

            foreach (IPrioritisedCommandHandler handlerTemplate in handlers)
            {
                object baseHandler = null;
                try
                {
                    baseHandler = _commandHandlerFactory.Create(handlerTemplate.CommandHandlerType);

                    if (baseHandler is ICommandHandler handler)
                    {
                        result = await _commandHandlerExecuter.ExecuteAsync(handler, command, result, cancellationToken);
                    }
                    else
                    {
                        if (baseHandler is IPipelineAwareCommandHandler chainHandler)
                        {
                            PipelineAwareCommandHandlerResult <TResult> chainResult =
                                await _pipelineAwareCommandHandlerExecuter.ExecuteAsync(chainHandler, command, result, cancellationToken);

                            result = chainResult.Result;
                            if (chainResult.ShouldStop)
                            {
                                break;
                            }
                        }
                        else
                        {
                            throw new UnableToExecuteHandlerException("Unexpected result type");
                        }
                    }
                }
                catch (Exception ex)
                {
                    bool shouldContinue =
                        await _commandExecutionExceptionHandler.HandleException(ex, baseHandler, handlerIndex, command,
                                                                                dispatchContext);

                    if (!shouldContinue)
                    {
                        break;
                    }
                }
                handlerIndex++;
            }

            return(result);
        }
        public async Task ExecutesCancellableHandlerWithResult()
        {
            // Arrange
            PipelineAwareCommandHandlerExecuter          testSubject = new PipelineAwareCommandHandlerExecuter();
            CancellableSimpleCommandPipelineAwareHandler handler     = new CancellableSimpleCommandPipelineAwareHandler();
            SimpleCommand command = new SimpleCommand();

            // Act
            PipelineAwareCommandHandlerResult <SimpleResult> result = await testSubject.ExecuteAsync(handler, command, null, CancellationToken.None);

            // Assert
            Assert.Single(result.Result.Handlers);
            Assert.Equal(typeof(CancellableSimpleCommandPipelineAwareHandler), result.Result.Handlers.Single());
        }