Обработка ошибок / исключений в конвейере посредника с использованием CQRS?

Я пытаюсь следоватьэта почта Джимми Богарда (Jimmy Bogard) для реализации посреднического конвейера, чтобы я мог использовать обработчики запросов pre / post для выполнения некоторой работы. Из комментариев к этой статье я прихожу к этомуGithub Gist, Я не совсем понимаю, как все это подключить, так что вот мой первый шаг. К вашему сведению - я использую Autofac для DI и Web Api 2. После CQRS, вот запрос.

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>();
    }

Вот текущий контроллер web api 2, показывающий 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);
    }
}

Наконец, вот код разрешения зависимости:

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);
}

Я получаю в GetAccountRequestValidationHandler. Тем не менее, когда проверка завершается неудачно (был передан идентификатор 0), как я могу вызвать исключение или остановить выполнение конвейера? Как мне вернуть .WithMessage?

Ответы на вопрос(1)

Ваш ответ на вопрос