【发布时间】:2019-10-21 11:47:04
【问题描述】:
我有这样的 MediatR 管道行为:
public class FailFastRequestBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
private readonly IEnumerable<IValidator> _validators;
public FailFastRequestBehavior(IEnumerable<IValidator<TRequest>> validators)
{
_validators = validators;
}
public Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
var failures = _validators
.Select(async v => await v.ValidateAsync(request))
.SelectMany(result => result.Result.Errors)
.Where(f => f != null);
return failures.Any()
? Errors(failures)
: next();
}
...
}
MediatR 命令如下:
public class MyUseCase
{
public class Command : IRequest<CommandResponse>
{
...
}
public class Validator : AbstractValidator<Command>
{
...
}
public class Handler<T>: IRequestHandler<T, CommandResponse>
{
...
}
}
验证器在Startup.cs 上注册,如下所示:
AssemblyScanner
.FindValidatorsInAssembly(Assembly.GetAssembly(typeof(MyUseCase)))
.ForEach(result =>
services.AddScoped(result.InterfaceType, result.ValidatorType));
这适用于MyUseCase.Validator,它被注入管道并被执行,验证MyUseCase.Command。
但它是一个大型应用程序,许多命令都有共同的属性,即每个订单操作都会收到一个OrderId,我必须检查 Id 是否有效,实体是否存在于数据库中,经过身份验证的用户是否是所有者正在修改的订单等。
所以我尝试创建以下接口和验证器:
public interface IOrder
{
string OrderId { get; set; }
}
public class IOrderValidator : AbstractValidator<IOrder>
{
public IOrderValidator()
{
CascadeMode = CascadeMode.StopOnFirstFailure;
RuleFor(x => x.OrderId)
.Rule1()
.Rule2()
.Rule3()
.RuleN()
}
}
最后我把命令改成了这样:
public class MyUseCase
{
public class Command : IRequest<CommandResponse>: IOrder
{
...
}
public class Validator : AbstractValidator<Command>
{
...
}
public class Handler<T>: IRequestHandler<T, CommandResponse>
{
...
}
}
问题是IOrderValidator没有注入管道,只有MyUseCase.Validator是。
我在这里遗漏了什么,或者甚至可以在管道中注入多个验证器吗?
【问题讨论】:
-
您只需将
IOrderValidator注册为IValidator<IOrder>基本上更改汇编扫描仪的代码
标签: c# asp.net-core fluentvalidation mediatr