ValidationModules.SourceGenerator
1.2.0
dotnet add package ValidationModules.SourceGenerator --version 1.2.0
NuGet\Install-Package ValidationModules.SourceGenerator -Version 1.2.0
<PackageReference Include="ValidationModules.SourceGenerator" Version="1.2.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="ValidationModules.SourceGenerator" Version="1.2.0" />
<PackageReference Include="ValidationModules.SourceGenerator"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add ValidationModules.SourceGenerator --version 1.2.0
#r "nuget: ValidationModules.SourceGenerator, 1.2.0"
#:package ValidationModules.SourceGenerator@1.2.0
#addin nuget:?package=ValidationModules.SourceGenerator&version=1.2.0
#tool nuget:?package=ValidationModules.SourceGenerator&version=1.2.0
ValidationModules
ValidationModules writes the validators for your .NET types at build time. You declare rules with attributes on a model, or in a rules class. A source generator turns them into a validator class made of ordinary C# checks. The validators read members directly instead of through reflection, so they work in trimmed and Native AOT applications.
Documentation: https://ipjohnson.github.io/ValidationModules/
Install
dotnet add package ValidationModules.Runtime
dotnet add package ValidationModules.SourceGenerator
The runtime targets .NET 8 and .NET 10.
Example
using ValidationModules.Constraints;
public sealed class SignUp
{
[Required, EmailAddress]
public string? Email { get; init; }
[Required, StringLength(40, Min = 3)]
public string? DisplayName { get; init; }
[Range(18, 120)]
public int Age { get; init; }
}
The generator writes a class named SignUpValidator that checks these rules. It also writes one
extension method that registers every validator in the project. The method is named after the
assembly, so a project named Shop gets AddShopValidators().
using Microsoft.Extensions.DependencyInjection;
using ValidationModules;
var services = new ServiceCollection();
services.AddShopValidators();
using var provider = services.BuildServiceProvider();
var validator = provider.GetRequiredService<IValidatorFor<SignUp>>();
var result = validator.Validate(
new SignUp
{
Email = "not-an-email",
DisplayName = "",
Age = 12,
}
);
foreach (var error in result.Errors)
{
Console.WriteLine($"{error.Field}: {error.Code}: {error.Message}");
}
email: email: email is not a valid email address.
displayName: required: displayName is required.
age: range: age must be between 18 and 120.
Every error has a Field path, a Code, a Message, and a Severity. The codes are stable, so
application logic and translations should key on Code rather than on the message text.
Rules that span members
An attribute sees one member. A rules class can compare several:
using ValidationModules;
public sealed class BookingRules : IValidationRulesFor<Booking>
{
public static void Describe(ValidationRules<Booking> rules, Booking x)
{
rules.Require(x.Guest).Length(1, 80);
rules.Range(x.Guests, 1, 8);
rules.Ensure(x.End > x.Start, message: "The stay must end after it starts.");
}
}
The generator reads Describe at build time and writes its rules into BookingValidator. The
method itself is never called.
Compared with DataAnnotations
- Most attributes share their names with
System.ComponentModel.DataAnnotations, such as[Required],[StringLength],[Range]and[EmailAddress]. - DataAnnotations finds and runs the attributes with reflection when you validate. Here the checks are compiled into the validator.
- An attribute on the wrong kind of member is a build error.
[Range]on a member whose type has no ordering reportsVM1003. - A model that already uses DataAnnotations attributes can be compiled as it is.
[StringLength(50)]is a maximum here too. DataAnnotations names the minimumMinimumLength, and this library names itMin.
Packages
| Package | Use it for |
|---|---|
ValidationModules.Runtime |
Attributes, the validator interfaces, results, and service registration. Always required. |
ValidationModules.SourceGenerator |
The source generator and its analyzers. Always required. |
ValidationModules.AspNetCore |
Validating minimal API arguments and returning RFC 9457 problem details. |
ValidationModules.Options |
Validating options classes when the host starts. |
ValidationModules.Messages |
Error messages in German, Spanish, French, Japanese and Chinese. |
ValidationModules.SourceGenerator.Impl |
The generator's source, for building your own generator on top of it. |
Documentation
Contributing
AGENTS.md describes how to build and test the repository, and the conventions the code follows.
License
MIT. See LICENSE.txt.
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on ValidationModules.SourceGenerator:
| Package | Downloads |
|---|---|
|
ValidationModules.Messages
Every built-in language for ValidationModules' error messages, shipped as data: the *.validation-messages.json files compile into your assembly at your build, validated against your runtime's shape inventory. All languages by default; set <ValidationModulesLanguages>fr;de</ValidationModulesLanguages> to compile exactly those, or 'none' to opt out - excluded languages are absent from the binary, not carried and ignored. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.2.0 | 0 | 9/25/2026 |
| 1.1.0 | 214 | 9/16/2026 |
| 1.0.0 | 188 | 8/31/2026 |
| 1.0.0-rc1015 | 120 | 8/31/2026 |
| 1.0.0-rc1014 | 115 | 8/30/2026 |
| 1.0.0-rc1013 | 114 | 8/30/2026 |
| 1.0.0-rc1012 | 92 | 8/29/2026 |
| 1.0.0-rc1011 | 91 | 8/29/2026 |
| 1.0.0-rc1010 | 93 | 8/29/2026 |
| 1.0.0-rc1009 | 96 | 8/28/2026 |
| 1.0.0-rc1008 | 103 | 8/28/2026 |
| 1.0.0-rc1007 | 123 | 8/27/2026 |
| 1.0.0-rc1006 | 117 | 8/16/2026 |
| 1.0.0-rc1005 | 111 | 8/16/2026 |
| 1.0.0-rc1004 | 113 | 8/16/2026 |
| 1.0.0-rc1003 | 109 | 8/14/2026 |
| 1.0.0-rc1002 | 104 | 8/14/2026 |
| 0.1.0-alpha.1 | 86 | 8/13/2026 |