The process is exactly the same, you just need to change the interface to use the new interface IPipelineBehavior<TRequest, TResponse> .
public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse> { private readonly IEnumerable<IValidator<TRequest>> _validators; public ValidationBehavior(IEnumerable<IValidator<TRequest>> validators) { _validators = validators; } public Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next) { var context = new ValidationContext(request); var failures = _validators .Select(v => v.Validate(context)) .SelectMany(result => result.Errors) .Where(f => f != null) .ToList(); if (failures.Count != 0) { throw new ValidationException(failures); } return next(); } }
For validators, you must register all validators as an IValidator<TRequest> in the built-in container so that they are introduced into the behavior. If you do not want to register them one by one, I suggest you take a look at the large Scrutor library , which provides the ability to scan assemblies, This way it will find your validators.
In addition, in the new system, you no longer use the decorator template, you simply register your general behavior in the container, and MediatR will automatically select it. It might look something like this:
var services = new ServiceCollection(); services.AddMediatR(typeof(Program)); services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>)); var provider = services.BuildServiceProvider();
Mickaël derriey
source share