/// <inheritdoc />
        public async Task ProcessAsync(
            ICommandContext <TCommand, TResult> context,
            CommandPipelineDelegate <TCommand, TResult> next,
            CancellationToken cancellationToken)
        {
            _logger.CommandProcessing(context);

            var stopwatch = new Stopwatch();

            stopwatch.Start();
            try
            {
                await next(context, cancellationToken)
                .ConfigureAwait(false);

                stopwatch.Stop();

                if (!context.IsFailed)
                {
                    _logger.CommandProcessed(context, stopwatch.Elapsed);
                }
                else
                {
                    _logger.CommandFailed(context, context.Error);
                }
            }
            catch (Exception exception)
            {
                _logger.CommandFailed(context, exception);
                throw;
            }
        }
        /// <inheritdoc />
        public async Task ProcessAsync(
            ICommandContext <TCommand, TResult> context,
            CommandPipelineDelegate <TCommand, TResult> next,
            CancellationToken cancellationToken)
        {
            await _validator.ValidateAndThrowAsync(context.Command, cancellationToken : cancellationToken)
            .ConfigureAwait(false);

            await next(context, cancellationToken)
            .ConfigureAwait(false);
        }
        /// <inheritdoc />
        public async Task ProcessAsync(
            ICommandContext <TCommand, TResult> context,
            CommandPipelineDelegate <TCommand, TResult> next,
            CancellationToken cancellationToken)
        {
            await next(context, cancellationToken)
            .ConfigureAwait(false);

            if (!context.IsFailed)
            {
                foreach (IPostCommandHandler <TCommand, TResult> handler in _handlers)
                {
                    await handler.OnHandledAsync(context, cancellationToken)
                    .ConfigureAwait(false);
                }
            }
        }