using FluentValidation; using MediatR; using Events.WebAPI.Contract.DTOs; using Events.WebAPI.Contract.Queries.Generic; namespace Events.WebAPI.Contract.Validation; public static class ForeignKeyValueValidatorExtension { public static IRuleBuilderOptions ForeignKeyExists( this IRuleBuilder ruleBuilder, IMediator mediator, IValidationMessageProvider validationMessageProvider, ValidationMessage? validationMessage = null) where TDto : IHasIdAsPK where TPK : IEquatable { ValidationMessage message = validationMessage ?? validationMessageProvider.ForeignKeyNotFound("{PropertyName}"); return ruleBuilder.MustAsync(new ForeignKeyValueValidator(mediator).Validate) .WithMessage(message.Message) .WithErrorCode(message.Code); } private class ForeignKeyValueValidator where TDto : IHasIdAsPK where TPK : IEquatable { private readonly IMediator mediator; public ForeignKeyValueValidator(IMediator mediator) { this.mediator = mediator; } public async Task Validate(TCommand command, TPK value, ValidationContext validationContext, CancellationToken cancellationToken) { var query = new DoesItemExistsQuery(value); try { bool itemExists = await mediator.Send(query, cancellationToken); return itemExists; } catch (Exception exc) { validationContext.AddFailure(exc.Message); return false; } } } }