メディエータのパイプラインを実装するために、私はthis postをJimmy Bogardに追いかけようとしています。そのため、前/後要求ハンドラを使用して作業を行うことができます。その記事のコメントから私はこれに来るgithub gist。私はまだこれをすべてフックする方法を理解していないので、ここに私の最初の行くことです。 FYI - 私はDIとWeb Api 2のためにAutofacを使用しています。CQRSの後に、ここではクエリです。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>();
}
はHTTPGET示す現在のウェブAPI 2コントローラです。私はGetAccountRequestValidationHandlerに取得しています
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);
}
:
[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);
}
}
は最後に、ここで依存関係解決コードです。しかし、検証に失敗すると(0のIDが渡されます)、どのように例外をスローするか、パイプラインの実行を停止しますか? .WithMessageを返すにはどうしたらいいですか?