< Summary

Information
Class: NexusLabs.Needlr.FluentValidation.FluentOptionsValidator<T>
Assembly: NexusLabs.Needlr.FluentValidation
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.FluentValidation/FluentValidatorWrapper.cs
Line coverage
100%
Covered lines: 2
Uncovered lines: 0
Coverable lines: 2
Total lines: 119
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
NexusLabs.Needlr.Generators.IOptionsValidator<TOptions>.Validate(...)100%11100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.FluentValidation/FluentValidatorWrapper.cs

#LineLine coverage
 1using FluentValidation;
 2
 3using NexusLabs.Needlr.Generators;
 4
 5namespace NexusLabs.Needlr.FluentValidation;
 6
 7/// <summary>
 8/// Wraps a FluentValidation <see cref="IValidator{T}"/> to implement Needlr's
 9/// <see cref="IOptionsValidator{T}"/> interface.
 10/// </summary>
 11/// <typeparam name="TOptions">The options type being validated.</typeparam>
 12/// <typeparam name="TValidator">The FluentValidation validator type.</typeparam>
 13/// <remarks>
 14/// <para>
 15/// This wrapper allows FluentValidation validators to be used with the
 16/// <c>[Options(Validator = typeof(...))]</c> attribute by implementing
 17/// the <see cref="IOptionsValidator{T}"/> interface.
 18/// </para>
 19/// <para>
 20/// Example usage:
 21/// <code>
 22/// // The FluentValidation validator
 23/// public class DatabaseOptionsValidator : AbstractValidator&lt;DatabaseOptions&gt;
 24/// {
 25///     public DatabaseOptionsValidator()
 26///     {
 27///         RuleFor(x => x.ConnectionString).NotEmpty();
 28///     }
 29/// }
 30///
 31/// // Wrap it for use with Needlr
 32/// public class DatabaseOptionsNeedlrValidator
 33///     : FluentValidatorWrapper&lt;DatabaseOptions, DatabaseOptionsValidator&gt;
 34/// {
 35///     public DatabaseOptionsNeedlrValidator() : base(new DatabaseOptionsValidator()) { }
 36/// }
 37///
 38/// // Use with [Options]
 39/// [Options(ValidateOnStart = true, Validator = typeof(DatabaseOptionsNeedlrValidator))]
 40/// public class DatabaseOptions { ... }
 41/// </code>
 42/// </para>
 43/// </remarks>
 44public class FluentValidatorWrapper<TOptions, TValidator> : IOptionsValidator<TOptions>
 45    where TOptions : class
 46    where TValidator : IValidator<TOptions>
 47{
 48    private readonly TValidator _validator;
 49
 50    /// <summary>
 51    /// Initializes a new instance wrapping the specified FluentValidation validator.
 52    /// </summary>
 53    /// <param name="validator">The FluentValidation validator to wrap.</param>
 54    public FluentValidatorWrapper(TValidator validator)
 55    {
 56        _validator = validator ?? throw new ArgumentNullException(nameof(validator));
 57    }
 58
 59    /// <summary>
 60    /// Validates the specified options instance using FluentValidation.
 61    /// </summary>
 62    /// <param name="options">The options instance to validate.</param>
 63    /// <returns>An enumerable of validation errors.</returns>
 64    public IEnumerable<ValidationError> Validate(TOptions options)
 65    {
 66        var result = _validator.Validate(options);
 67        return result.ToValidationErrors();
 68    }
 69}
 70
 71/// <summary>
 72/// A convenience base class for creating Needlr-compatible validators from FluentValidation validators.
 73/// </summary>
 74/// <typeparam name="TOptions">The options type being validated.</typeparam>
 75/// <remarks>
 76/// <para>
 77/// Inherit from this class and define your validation rules in the constructor.
 78/// The resulting class can be used directly with <c>[Options(Validator = typeof(...))]</c>.
 79/// </para>
 80/// <para>
 81/// Example:
 82/// <code>
 83/// [Options(ValidateOnStart = true, Validator = typeof(DatabaseOptionsValidator))]
 84/// public class DatabaseOptions
 85/// {
 86///     public string ConnectionString { get; set; } = "";
 87///     public int MaxConnections { get; set; } = 100;
 88/// }
 89///
 90/// public class DatabaseOptionsValidator : FluentOptionsValidator&lt;DatabaseOptions&gt;
 91/// {
 92///     public DatabaseOptionsValidator()
 93///     {
 94///         RuleFor(x => x.ConnectionString)
 95///             .NotEmpty()
 96///             .WithMessage("Connection string is required");
 97///
 98///         RuleFor(x => x.MaxConnections)
 99///             .InclusiveBetween(1, 1000)
 100///             .WithMessage("Max connections must be between 1 and 1000");
 101///     }
 102/// }
 103/// </code>
 104/// </para>
 105/// </remarks>
 106public abstract class FluentOptionsValidator<TOptions> : AbstractValidator<TOptions>, IOptionsValidator<TOptions>
 107    where TOptions : class
 108{
 109    /// <summary>
 110    /// Validates the specified options instance.
 111    /// </summary>
 112    /// <param name="options">The options instance to validate.</param>
 113    /// <returns>An enumerable of validation errors.</returns>
 114    IEnumerable<ValidationError> IOptionsValidator<TOptions>.Validate(TOptions options)
 115    {
 1116        var result = base.Validate(options);
 1117        return result.ToValidationErrors();
 118    }
 119}