Manejo de errores / excepciones en una tubería de mediador usando CQRS?

Estoy tratando de seguiresta publicación por Jimmy Bogard para implementar una canalización de mediador para que pueda usar los controladores de solicitud previa / posterior para hacer un poco de trabajo. De los comentarios sobre ese artículo llego a estoGithub Gist. Todavía no entiendo cómo conectar todo esto, así que aquí está mi primer intento. FYI: estoy usando Autofac para DI y Web Api 2. Después de CQRS, aquí hay una consulta.

public class GetAccountRequest : IAsyncRequest<GetAccountResponse>
{
    public int Id { get; set; }
}

//try using fluent validation
public class GetAccountRequestValidationHandler 
    : AbstractValidator<GetAccountRequest>, IAsyncPreRequestHandler<GetAccountRequest>
{
    public GetAccountRequestValidationHandler() {
        RuleFor(m => m.Id).GreaterThan(0).WithMessage("Please specify an id.");
    }

    public Task Handle(GetAccountRequest request) {
        Debug.WriteLine("GetAccountPreProcessor Handler");   
        return Task.FromResult(true);
    }
}

public class GetAccountResponse
{
    public int AccountId { get; set; }
    public string Name { get; set; }
    public string AccountNumber { get; set; }
    public string Nickname { get; set; }
    public string PhoneNumber { get; set; }
    public List<OrderAckNotification> OrderAckNotifications { get; set; }

    public class OrderAckNotification {
        public int Id { get; set; }
        public bool IsDefault { get; set; }
        public string Description { get; set; }
        public string Type { get; set; }
    }
}

GetAccountRequestHandler:

public class GetAccountRequestHandler 
    : IAsyncRequestHandler<GetAccountRequest, GetAccountResponse>
{
    private readonly IRedStripeDbContext _dbContext;

    public GetAccountRequestHandler(IRedStripeDbContext redStripeDbContext)
    {
        _dbContext = redStripeDbContext;
    }

    public async Task<GetAccountResponse> Handle(GetAccountRequest message)
    {
        //some mapping code here.. omitted for brevity
        Mapper.AssertConfigurationIsValid();

        return await _dbContext.Accounts.Where(a => a.AccountId == message.Id)
            .ProjectToSingleOrDefaultAsync<GetAccountResponse>();
    }

Aquí está el controlador actual de la API web 2 que muestra el HttpGet.

[RoutePrefix("api/Accounts")]
public class AccountsController : ApiController
{
    private readonly IMediator _mediator;

    public AccountsController(IMediator mediator)
    {
        _mediator = mediator;
    }

    // GET: api/Accounts/2
    [Route("{id:int}")]
    [HttpGet]
    public async Task<IHttpActionResult> GetById([FromUri] GetAccountRequest request)
    {
        var model = await _mediator.SendAsync<GetAccountResponse>(request);

        return Ok(model);
    }
}

Finalmente aquí está el código de resolución de dependencia:

public void Configuration(IAppBuilder app)
{
    var config = new HttpConfiguration();

    ConfigureDependencyInjection(app, config);

    WebApiConfig.Register(config);
    app.UseWebApi(config);
}

private static void ConfigureDependencyInjection(IAppBuilder app, 
    HttpConfiguration config)
{
    var builder = new ContainerBuilder();
    builder.RegisterSource(new ContravariantRegistrationSource());
    builder.RegisterAssemblyTypes(typeof(IMediator).Assembly).AsImplementedInterfaces();

    builder.Register<SingleInstanceFactory>(ctx =>
    {
        var c = ctx.Resolve<IComponentContext>();
        return t => c.Resolve(t);
    });

    builder.Register<MultiInstanceFactory>(ctx =>
    {
        var c = ctx.Resolve<IComponentContext>();
        return t => (IEnumerable<object>)c.Resolve(
            typeof(IEnumerable<>).MakeGenericType(t));
    });

    //register all pre handlers
    builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
        .As(type => type.GetInterfaces()
            .Where(t => t.IsClosedTypeOf(typeof(IAsyncPreRequestHandler<>))));

    //register all post handlers
    builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
        .As(type => type.GetInterfaces()
            .Where(t => t.IsClosedTypeOf(typeof(IAsyncPostRequestHandler<,>))));


    //register all handlers
    builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
        .As(type => type.GetInterfaces()
            .Where(t => t.IsClosedTypeOf(typeof(IAsyncRequestHandler<,>)))
            .Select(t => new KeyedService("asyncRequestHandler", t)));

    //register pipeline decorator
    builder.RegisterGenericDecorator(typeof(AsyncMediatorPipeline<,>), 
        typeof(IAsyncRequestHandler<,>), "asyncRequestHandler");

    // Register Web API controller in executing assembly.
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).InstancePerRequest();

    //register RedStripeDbContext
    builder.RegisterType<RedStripeDbContext>().As<IRedStripeDbContext>()
        .InstancePerRequest();

    builder.RegisterType<AutofacServiceLocator>().AsImplementedInterfaces();
    var container = builder.Build();

    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

    // This should be the first middleware added to the IAppBuilder.
    app.UseAutofacMiddleware(container);

    // Make sure the Autofac lifetime scope is passed to Web API.
    app.UseAutofacWebApi(config);
}

Me estoy metiendo en el GetAccountRequestValidationHandler. Sin embargo, cuando la validación falla (se pasó una identificación de 0), ¿cómo lanzo una excepción o detengo la ejecución de la canalización? ¿Cómo devuelvo el .WithMessage?

Respuestas a la pregunta(1)

Su respuesta a la pregunta