Compile-time FluentValidation wiring for .NET.
AutoValidate.Generator uses Roslyn source generators to automatically discover your AbstractValidator<T> subclasses and generate AddValidators() on IServiceCollection — no assembly scanning, no reflection, no runtime overhead.
dotnet add package AutoValidate.Generator
dotnet add package FluentValidationDefine your validators as normal:
public class Order
{
public string CustomerName { get; set; } = "";
public decimal Total { get; set; }
}
public class OrderValidator : AbstractValidator<Order>
{
public OrderValidator()
{
RuleFor(x => x.CustomerName).NotEmpty();
RuleFor(x => x.Total).GreaterThan(0);
}
}Register everything in one line — no manual wiring:
builder.Services.AddValidators();AutoValidate discovers every non-abstract AbstractValidator<T> in your assembly at compile time and generates the registration code for you.
Exclude a validator from auto-registration (e.g. test validators, base classes you register manually):
[SkipValidator]
public class TestOrderValidator : AbstractValidator<Order> { }Override the DI lifetime. Default is Scoped.
using AutoValidate;
// Singleton — validator has no mutable state
[ValidatorLifetime(ValidatorLifetime.Singleton)]
public class ConfigValidator : AbstractValidator<AppConfig> { }
// Transient — validator has per-request dependencies
[ValidatorLifetime(ValidatorLifetime.Transient)]
public class RequestValidator : AbstractValidator<CreateOrderRequest> { }Available lifetimes: ValidatorLifetime.Scoped (default), ValidatorLifetime.Singleton, ValidatorLifetime.Transient.
Register a hosted service that validates an instance of the model when the application starts. Useful for validating configuration objects.
[ValidateOnStartup]
public class AppSettingsValidator : AbstractValidator<AppSettings>
{
public AppSettingsValidator()
{
RuleFor(x => x.ConnectionString).NotEmpty();
RuleFor(x => x.ApiKey).MinimumLength(32);
}
}AppSettings must be registered in DI (e.g. via services.AddSingleton(appSettings)). If the instance is not found, startup validation is silently skipped.
If validation fails at startup, an InvalidOperationException is thrown — your app will not start.
WithValidation<T>() attaches a validation endpoint filter that automatically returns 400 ValidationProblem for invalid requests:
app.MapPost("/orders", (Order order) => Results.Ok())
.WithValidation<Order>();The generated ValidationFilter<T> resolves IValidator<T> from DI, validates the first matching argument, and returns RFC 7807-compliant validation errors.
Requires .NET 7 or later.
At build time, the generator:
- Scans all type declarations with a base list
- Walks the inheritance chain looking for
FluentValidation.AbstractValidator<T> - Skips abstract classes and
[SkipValidator]-decorated types - Emits
AddValidators()with the correctAddScoped/AddSingleton/AddTransientcalls - Emits
ValidationFilter<T>andValidatorStartupService<T>helpers as needed
No reflection. No assembly scanning. No runtime cost.
| Code | Severity | Description |
|---|---|---|
| AV001 | Warning | Multiple validators found for the same model type. Only the first is registered. |
| AV002 | Warning | AutoValidate attribute on a class that does not inherit AbstractValidator<T>. |
| Feature | AddValidatorsFromAssembly() |
AutoValidate.Generator |
|---|---|---|
| Discovery | Runtime reflection | Compile-time |
| Registration overhead | Assembly scan on startup | Zero |
| AOT / NativeAOT compatible | ❌ | ✅ |
| IDE navigation | ❌ | ✅ (generated code is inspectable) |
| Startup validation | Manual | [ValidateOnStartup] |
🌐 Full suite overview: swevo.github.io
| Package | Description |
|---|---|
| AutoWire | Compile-time DI auto-registration — [Scoped]/[Singleton]/[Transient] generates IServiceCollection code. Zero reflection. |
| AutoMap.Generator | Compile-time object mapping — [Map(typeof(Dto))] generates ToDto() extension methods. Zero reflection, AOT-safe. |
| AutoResult.Generator | Compile-time Result<T> monad — [TryWrap] generates Try*() wrappers for sync, async and void methods. |
| AutoQuery.Generator | Compile-time LINQ query specs — [QuerySpec(typeof(T))] generates Apply(IQueryable<T>). |
| AutoDispatch.Generator | Compile-time CQRS dispatcher — [Handler] generates a strongly-typed IDispatcher. No IRequest<T>, no reflection. |
| AutoLog.Generator | Compile-time high-performance logging — [Log(Level, Message)] on a partial method generates LoggerMessage.Define. AOT-safe. |
| AutoHttpClient.Generator | Compile-time typed HTTP client — [HttpClient] on an interface generates a strongly-typed client. AOT-safe Refit alternative. |
| Package | Downloads | Description |
|---|---|---|
| AutoWire | Compile-time dependency injection auto-registration for | |
| AutoMap.Generator | Compile-time object mapping for | |
| AutoQuery.Generator | Compile-time query composition for IQueryable using Roslyn incremental source generators | |
| AutoArchitecture | Compile-time architecture/dependency-rule enforcement for | |
| AutoHttpClient.Generator | Compile-time typed HTTP client generation for | |
| AutoDispatch.Generator | Compile-time CQRS dispatcher for | |
| AutoLog.Generator | Compile-time high-performance logging for |
MIT © Justin Bannister