The ExpressValidator.Extensions.DependencyInjection package extends ExpressValidator to provide integration with Microsoft Dependency Injection.
- Automatic DI Registration: Configures and registers
IExpressValidator<T>with Microsoft's Dependency Injection container. - Class-Based Configuration: Define validation rules via dedicated configurator classes inheriting from
ValidatorConfigurator<T>, providing an alternative to inline configuration. - Dynamic Parameter Updates: Registers
IExpressValidatorBuilder<T, TOptions>to automatically update validation parameters when configuration options change. - Automatic Reload Capability: Automatically reload validation rules when configuration changes using
IExpressValidatorWithReload<T>.
Explore the API documentation and in-depth details on DeepWiki.
Register an IExpressValidator<T> implementation in the dependency injection (DI) container using the AddExpressValidator method, then inject and use it in a consuming service:
using ExpressValidator;
using ExpressValidator.Extensions.DependencyInjection;
using FluentValidation;
var builder = WebApplication.CreateBuilder(args);
// Registers the validator for ObjToValidate with specified validation rules.
builder.Services.AddExpressValidator<ObjToValidate>(b =>
b.AddProperty(o => o.I)
.WithValidation(o => o.GreaterThan(5)
.WithMessage("Must be greater than 5!")));
// Registers the service that will use the validator.
builder.Services.AddTransient<IGuessTheNumberService, GuessTheNumberService>();
var app = builder.Build();
app.MapGet("/guess", (IGuessTheNumberService service) =>
{
var (Result, Message) = service.Guess();
if (!Result)
{
return Results.BadRequest(Message);
}
// Additional logic here...
});
await app.RunAsync();
// ... (Other code omitted for brevity)
// Service interface definition.
public interface IGuessTheNumberService
{
(bool Result, string Message) Guess();
}
// Service implementation that uses the validator.
public class GuessTheNumberService : IGuessTheNumberService
{
private readonly IExpressValidator<ObjToValidate> _expressValidator;
public GuessTheNumberService(IExpressValidator<ObjToValidate> expressValidator)
{
_expressValidator = expressValidator;
}
public (bool Result, string Message) Guess()
{
...
var vr = _expressValidator.Validate(objToValidate);
if (!vr.IsValid)
{
...
}
// ... (Additional logic)
}
}
// ... (Other code omitted for brevity)As an alternative to inline configuration, you can define validation rules by creating a dedicated configurator class that inherits from ValidatorConfigurator<T>, where T is the type being validated:
/// <summary>
/// Configures validation rules for ObjToValidate.
/// </summary>
public class GuessValidatorConfigurator : ValidatorConfigurator<ObjToValidate>
{
/// <summary>
/// Configures the validator builder with rules.
/// </summary>
public override void Configure(ExpressValidatorBuilder<ObjToValidate> expressValidatorBuilder)
=> expressValidatorBuilder
.AddProperty(o => o.I)
.WithValidation((o) => o.GreaterThan(5));
}Then use AddExpressValidation method to register the configurator in DI:
var builder = WebApplication.CreateBuilder(args);
// Scans the assembly and registers validators from configurators.
builder.Services.AddExpressValidation(Assembly.GetExecutingAssembly());
// Registers the service that will use the validator.
builder.Services.AddTransient<IGuessTheNumberService, GuessTheNumberService>();
// ... (Application build and run code omitted; same as in Quick Start)
// The GuessTheNumberService implementation remains the same as in the Quick Start example.
// ... (Other code omitted for brevity)In this approach, register an IExpressValidatorBuilder<T, TOptions> implementation (instead of IExpressValidator<T>) in the DI container by calling the AddExpressValidatorBuilder method.
var builder = WebApplication.CreateBuilder(args);
// Registers the validator builder with options-dependent rules.
builder.Services.AddExpressValidatorBuilder<ObjToValidate, ValidationParametersOptions>(b =>
b.AddProperty(o => o.I)
.WithValidation((to, rbo) => rbo.GreaterThan(to.IGreaterThanValue)
.WithMessage($"Must be greater than {to.IGreaterThanValue}!")));
builder.Services.AddTransient<IAdvancedNumberGuessingService, AdvancedNumberGuessingService>();
// Configures options from the application settings.
builder.Services.Configure<ValidationParametersOptions>(builder.Configuration.GetSection("ValidationParameters"));
var app = builder.Build();
app.MapGet("/complexguess", (IAdvancedNumberGuessingService service) =>
{
var (Result, Message) = service.ComplexGuess();
if (!Result)
{
return Results.BadRequest(Message);
}
// Additional logic here...
});
app.Run();
// Service interface definition:
public interface IAdvancedNumberGuessingService
{
(bool Result, string Message) ComplexGuess();
}
// Service implementation that builds and uses the validator with options.
public class AdvancedNumberGuessingService : IAdvancedNumberGuessingService
{
private readonly ValidationParametersOptions _validateOptions;
private readonly IExpressValidatorBuilder<ObjToValidate, ValidationParametersOptions> _expressValidatorBuilder;
public AdvancedNumberGuessingService(IExpressValidatorBuilder<ObjToValidate, ValidationParametersOptions> expressValidatorBuilder,
IOptions<ValidationParametersOptions> validateOptions)
{
_validateOptions = validateOptions.Value;
_expressValidatorBuilder = expressValidatorBuilder;
}
//Updates options, rebuilds the validator, and validates.
public (bool Result, string Message) ComplexGuess()
{
...
ChangeValidateOptions();
var vr = _expressValidatorBuilder.Build(_validateOptions).Validate(objToValidate);
if (!vr.IsValid)
{
// ... (Handle invalid case)
}
// ... (Additional logic)
}
private void ChangeValidateOptions()
{
// ... (Option update logic omitted)
}
}In the appsettings.json
{
// ... (Other settings omitted)
"ValidationParameters": {
"IGreaterThanValue": 5
}
}To validate options when configuration changes - without restarting the application - use the AddExpressValidatorWithReload method:
var builder = WebApplication.CreateBuilder(args);
// Registers a reloadable validator that updates on configuration changes.
builder.Services.AddExpressValidatorWithReload<ObjToValidate, ValidationParametersOptions>(b =>
b.AddProperty(o => o.I)
.WithValidation((to, rbo) => rbo.GreaterThan(to.IGreaterThanValue)
.WithMessage($"Must be greater than {to.IGreaterThanValue}!")),
"ValidationParameters");
// Registers the reloadable service.
builder.Services.AddTransient<IReloadableNumberGuessingService, ReloadableNumberGuessingService>();
// Configures options from the application settings.
builder.Services.Configure<ValidationParametersOptions>(builder.Configuration.GetSection("ValidationParameters"));
var app = builder.Build();
app.MapGet("/guesswithreload", (IReloadableNumberGuessingService service) =>
{
var (Result, Message) = service.GuessWithReload();
if (!Result)
{
return Results.BadRequest(Message);
}
// Additional logic here...
});
// Service interface definition.
public interface IReloadableNumberGuessingService
{
(bool Result, string Message) GuessWithReload();
}
// Service implementation that uses the reloadable validator.
public class ReloadableNumberGuessingService : IReloadableNumberGuessingService
{
private readonly IExpressValidatorWithReload<ObjToValidate> _expressValidatorWithReload;
public ReloadableNumberGuessingService(IExpressValidatorWithReload<ObjToValidate> expressValidatorWithReload)
{
_expressValidatorWithReload = expressValidatorWithReload;
}
public (bool Result, string Message) GuessWithReload()
{
...
var vr = _expressValidatorWithReload.Validate(objToValidate);
if (!vr.IsValid)
{
...
}
}
}