mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-07-16 17:47:22 +00:00
Scaffold vertical-slice migration: Shared.Contracts, Shared.Application, MediatR
Begins the move to vertical-slice architecture. ResponseBody moves out of API.Core into Shared.Contracts so slices won't have to depend on the API host project for it. Shared.Application adds the MediatR pipeline's ValidationBehavior plus the cross-slice email commands that Features.Auth will send and Features.Emails will handle, keeping slices decoupled from each other.
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
using FluentValidation;
|
||||
using MediatR;
|
||||
|
||||
namespace Shared.Application.Behaviors;
|
||||
|
||||
/// <summary>
|
||||
/// MediatR pipeline behavior that runs all registered FluentValidation validators for a
|
||||
/// request before invoking its handler, short-circuiting with a <see cref="ValidationException"/>
|
||||
/// when any validator reports failures.
|
||||
/// </summary>
|
||||
public class ValidationBehavior<TRequest, TResponse>(IEnumerable<IValidator<TRequest>> validators)
|
||||
: IPipelineBehavior<TRequest, TResponse>
|
||||
where TRequest : IRequest<TResponse>
|
||||
{
|
||||
public async Task<TResponse> Handle(
|
||||
TRequest request,
|
||||
RequestHandlerDelegate<TResponse> next,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
if (!validators.Any())
|
||||
{
|
||||
return await next();
|
||||
}
|
||||
|
||||
var context = new ValidationContext<TRequest>(request);
|
||||
|
||||
var failures = (
|
||||
await Task.WhenAll(
|
||||
validators.Select(v => v.ValidateAsync(context, cancellationToken))
|
||||
)
|
||||
)
|
||||
.SelectMany(result => result.Errors)
|
||||
.Where(failure => failure != null)
|
||||
.ToList();
|
||||
|
||||
if (failures.Count > 0)
|
||||
{
|
||||
throw new ValidationException(failures);
|
||||
}
|
||||
|
||||
return await next();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user