2015-09-17 32 views
1

我正在使用Web Api 2,Autofac和MediatR(CQRS)。我有一个中介管道,具有前/后请求处理程序。这一切都很好。我正在尝试连接验证并用它装饰管线。CQRS ValidatorHandler无法识别FluentValidation验证器?

这里是我的Autofac DI代码:

public void Configuration(IAppBuilder app) 
{ 
    var config = new HttpConfiguration(); 
    FluentValidationModelValidatorProvider.Configure(config); 
    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(interfacetype => interfacetype.IsClosedTypeOf(typeof(IAsyncPreRequestHandler<>)))) 
     .InstancePerLifetimeScope(); 

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

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

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

    //register validator decorator 
    builder.RegisterGenericDecorator(
     typeof(ValidatorHandler<,>), 
     typeof(IAsyncRequestHandler<,>), 
     "asyncMediatorPipeline") 
     .InstancePerLifetimeScope(); 

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

这里是为ValidatorHandler:

public class ValidatorHandler<TRequest, TResponse> : IAsyncRequestHandler<TRequest, TResponse> where TRequest : IAsyncRequest<TResponse> 
{ 
    private readonly IAsyncRequestHandler<TRequest, TResponse> _inner; 
    private readonly IValidator<TRequest>[] _validators; 

    public ValidatorHandler(
     IAsyncRequestHandler<TRequest, TResponse> inner, 
     IValidator<TRequest>[] validators) 
    { 
     _inner = inner; 
     _validators = validators; 
    } 

    public async Task<TResponse> Handle(TRequest request) 
    { 
     var context = new ValidationContext(request); 

     var failures = _validators 
      .Select(v => v.Validate(context)) 
      .SelectMany(result => result.Errors) 
      .Where(f => f != null) 
      .ToList(); 

     if (failures.Any()) 
      throw new ValidationException(failures); 

     return await _inner.Handle(request); 
    } 
} 

下面是一个简单的查询:

[Validator(typeof(GetAccountRequestValidationHandler))] 
public class GetAccountRequest : IAsyncRequest<GetAccountResponse> 
{ 
    public int Id { get; set; } 
} 

这里是一口流利的验证处理程序:

public class GetAccountRequestValidationHandler : AbstractValidator<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 GetAccountRequestHandler : IAsyncRequestHandler<GetAccountRequest, GetAccountResponse> 
{ 
    private readonly IRedStripeDbContext _dbContext; 

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

    public async Task<GetAccountResponse> Handle(GetAccountRequest message) 
    { 
     return await _dbContext.Accounts.Where(a => a.AccountId == message.Id) 
      .ProjectToSingleOrDefaultAsync<GetAccountResponse>(); 
    } 
} 

最后这里是网页API 2 HTTPGET方法:

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

    return Ok(model); 
} 

我把断点所有的地方,当我打这个端点,第一我进入的东西是GetAccountRequestValidationHandler。然后我进入ValidatorHandler的构造函数。问题是,构造函数的IValidator []验证器参数始终为空。

我必须缺少一些流利的验证,并通过Autofac注册?任何帮助深表感谢。

回答

3

验证器类型必须在IoC中注册。将下面的内容添加到您的ConfigureDependencyInjection方法中应该做到这一点。

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) 
    .Where(t => t.Name.EndsWith("ValidationHandler")) 
    .AsImplementedInterfaces() 
    .InstancePerLifetimeScope(); 
相关问题