using FluentValidation;
using FluentValidation.Results;
using Microsoft.Extensions.Options;
namespace Vegasco.Server.Api.Common;
public static class ValidatorExtensions
{
///
/// Asynchronously validates an instance of against all instances in .
///
///
///
///
/// The failed validation results.
public static async Task> ValidateAllAsync(this IEnumerable> validators, T instance, CancellationToken cancellationToken = default)
{
List> validationTasks = validators
.Select(validator => validator.ValidateAsync(instance, cancellationToken))
.ToList();
await Task.WhenAll(validationTasks);
List failedValidations = validationTasks
.Select(x => x.Result)
.Where(x => !x.IsValid)
.ToList();
return failedValidations;
}
public static Dictionary ToCombinedDictionary(this IEnumerable validationResults)
{
// Use a hash set to avoid duplicate error messages.
Dictionary> combinedErrors = [];
foreach (ValidationFailure? error in validationResults.SelectMany(x => x.Errors))
{
if (!combinedErrors.TryGetValue(error.PropertyName, out HashSet? value))
{
value = [error.ErrorMessage];
combinedErrors[error.PropertyName] = value;
continue;
}
value.Add(error.ErrorMessage);
}
return combinedErrors.ToDictionary(x => x.Key, x => x.Value.ToArray());
}
public static OptionsBuilder ValidateFluently(this OptionsBuilder builder)
where T : class
{
builder.Services.AddTransient>(serviceProvider =>
{
IEnumerable> validators = serviceProvider.GetServices>() ?? [];
return new FluentValidationOptions(builder.Name, validators);
});
return builder;
}
}