的自定义 ICommand
public interface ICommand<TResponse>
: IRequest<ErrorOr<TResponse>>
{
}
public interface IQuery<TResponse>
: IRequest<ErrorOr<TResponse>>
{
}
public interface ICommandHandler<TCommand, TResponse>
: IRequestHandler<TCommand, ErrorOr<TResponse>>
where TCommand : ICommand<TResponse>
{
}
public interface IQueryHandler<TQuery, TResponse>
: IRequestHandler<TQuery, ErrorOr<TResponse>>
where TQuery : IQuery<TResponse>
{
}
我知道一种标准方法,其中 IPipelineBehavior 会向任何请求者触发,然后我们检查该请求者是否有验证器:
public class ValidationBehavion<TRequest, TResponse>
: IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
where TResponse : IErrorOr
{
private readonly IValidator<TRequest>? _validator;
public ValidationBehavion(IValidator<TRequest>? validator = null)
{
_validator = validator;
}
public async Task<TResponse> Handle(TRequest request,
RequestHandlerDelegate<TResponse> next,
CancellationToken cancellationToken)
{
if(_validator is null)
{
return await next();
}
var validationResult = await _validator.ValidateAsync(request);
if (validationResult.IsValid)
{
return await next();
}
var validationErrors = validationResult.Errors
.ConvertAll(error =>
Errors.Wands.NotValid(
error.PropertyName,
error.ErrorMessage));
return (dynamic)validationErrors;
}
}
由于命令和查询是分离的,我想我可以指定 ICommand 而不是 IRequest
public class ValidationBehavion<TRequest, TResponse>
: IPipelineBehavior<TRequest, ErrorOr<TResponse>>
where TRequest : ICommand<TResponse>
{
private readonly IValidator<TRequest> _validator;
public ValidationBehavion(IValidator<TRequest> validator)
{
_validator = validator;
}
public async Task<ErrorOr<TResponse>> Handle(TRequest request,
RequestHandlerDelegate<ErrorOr<TResponse>> next,
CancellationToken cancellationToken)
{
var validationResult = await _validator.ValidateAsync(request);
if (validationResult.IsValid)
{
return await next();
}
var validationErrors = validationResult.Errors
.ConvertAll(error =>
Errors.Wands.NotValid(
error.PropertyName,
error.ErrorMessage));
return validationErrors;
}
}
但是这个 IPipelineBehavior 根本不起作用,我不知道为什么。
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddMediatR(typeof(Startup));
services.AddValidatorsFromAssemblyContaining<Startup>();
// Register pipeline behaviors
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(AuthorizationBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(PerformanceBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(UnhandledExceptionBehavior<,>));
// Register request pre-processors and post-processors
services.AddTransient(typeof(IRequestPreProcessor<>), typeof(ValidationPreProcessor<>));
services.AddTransient(typeof(IRequestPostProcessor<,>), typeof(LoggingPostProcessor<,>));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
您在这里有完整的教程:https://argosco.io/using-ipipelinebehavior-irequestpreprocessor-and-irequestpostprocessor-in-a-net-core-api/net/