Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 63 additions & 55 deletions README.md

Large diffs are not rendered by default.

38 changes: 13 additions & 25 deletions later.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Just later

## Latest Update : 2025-10-05 => 05 October 2025
## Latest Update : 2025-10-06 => 06 October 2025



Expand Down Expand Up @@ -62,85 +62,73 @@ Why I have not tested : later



10) [https://github.com/Hookyns/validly]( https://github.com/Hookyns/validly) , https://github.com/Hookyns/validly
10) [https://github.com/pierre3/PlantUmlClassDiagramGenerator]( https://github.com/pierre3/PlantUmlClassDiagramGenerator) , https://github.com/pierre3/PlantUmlClassDiagramGenerator

Why I have not tested : later



11) [https://github.com/nuskey8/Csv-CSharp]( https://github.com/nuskey8/Csv-CSharp) , https://github.com/nuskey8/Csv-CSharp
11) [https://github.com/Stepami/visitor-net]( https://github.com/Stepami/visitor-net) , https://github.com/Stepami/visitor-net

Why I have not tested : later



12) [https://github.com/pierre3/PlantUmlClassDiagramGenerator]( https://github.com/pierre3/PlantUmlClassDiagramGenerator) , https://github.com/pierre3/PlantUmlClassDiagramGenerator
12) [https://github.com/SzymonHalucha/Minerals.AutoCommands]( https://github.com/SzymonHalucha/Minerals.AutoCommands) , https://github.com/SzymonHalucha/Minerals.AutoCommands

Why I have not tested : later



13) [https://github.com/Stepami/visitor-net]( https://github.com/Stepami/visitor-net) , https://github.com/Stepami/visitor-net
13) [https://github.com/Teleopti/Saspect]( https://github.com/Teleopti/Saspect) , https://github.com/Teleopti/Saspect

Why I have not tested : later



14) [https://github.com/SzymonHalucha/Minerals.AutoCommands]( https://github.com/SzymonHalucha/Minerals.AutoCommands) , https://github.com/SzymonHalucha/Minerals.AutoCommands
14) [Maui.BindableProperty.Generator]( https://github.com/rrmanzano/maui-bindableproperty-generator) , https://github.com/rrmanzano/maui-bindableproperty-generator

Why I have not tested : later



15) [https://github.com/Teleopti/Saspect]( https://github.com/Teleopti/Saspect) , https://github.com/Teleopti/Saspect
15) [Minerals.AutoCQRS]( https://github.com/SzymonHalucha/Minerals.AutoCQRS) , https://github.com/SzymonHalucha/Minerals.AutoCQRS

Why I have not tested : later



16) [Maui.BindableProperty.Generator]( https://github.com/rrmanzano/maui-bindableproperty-generator) , https://github.com/rrmanzano/maui-bindableproperty-generator
16) [Minerals.AutoDomain]( https://github.com/SzymonHalucha/Minerals.AutoDomain) , https://github.com/SzymonHalucha/Minerals.AutoDomain

Why I have not tested : later



17) [Minerals.AutoCQRS]( https://github.com/SzymonHalucha/Minerals.AutoCQRS) , https://github.com/SzymonHalucha/Minerals.AutoCQRS
17) [observable]( https://github.com/notanaverageman/Bindables) , https://github.com/notanaverageman/Bindables

Why I have not tested : later



18) [Minerals.AutoDomain]( https://github.com/SzymonHalucha/Minerals.AutoDomain) , https://github.com/SzymonHalucha/Minerals.AutoDomain
18) [RazorGen]( https://github.com/dartk/RazorGen) , https://github.com/dartk/RazorGen

Why I have not tested : later



19) [observable]( https://github.com/notanaverageman/Bindables) , https://github.com/notanaverageman/Bindables
19) [SourceCrafter.HttpServiceClientGenerator]( https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/) , https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/

Why I have not tested : later



20) [RazorGen]( https://github.com/dartk/RazorGen) , https://github.com/dartk/RazorGen
20) [ST.NSwag.ServerSourceGenerator]( https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator) , https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator

Why I have not tested : later



21) [SourceCrafter.HttpServiceClientGenerator]( https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/) , https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/

Why I have not tested : later



22) [ST.NSwag.ServerSourceGenerator]( https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator) , https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator

Why I have not tested : later



23) [StrongInject]( https://github.com/YairHalberstadt/stronginject/) , https://github.com/YairHalberstadt/stronginject/
21) [StrongInject]( https://github.com/YairHalberstadt/stronginject/) , https://github.com/YairHalberstadt/stronginject/

Why I have not tested : later

Expand Down
1 change: 1 addition & 0 deletions v2/Generator/all.csv
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,4 @@ Nr,Key,Source,Category
233,Vyaml, https://github.com/hadashiA/VYaml,Serializer
234,RapidEnum, https://github.com/hanachiru/RapidEnum,Enum
235,CsvCsharp, https://github.com/nuskey8/Csv-CSharp,Serializer
236,Validly, https://github.com/Hookyns/validly,Validator
1 change: 1 addition & 0 deletions v2/GeneratorData/Category.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@ public enum Category
AI=37,
RX=38,
Mixin=39,
Validator=40,
}

7 changes: 7 additions & 0 deletions v2/RSCGExamplesData/GeneratorDataRec.json
Original file line number Diff line number Diff line change
Expand Up @@ -1421,5 +1421,12 @@
"Category":16,
"dtStart": "2025-10-05T00:00:00",
"show": true
},

{
"ID":"Validly",
"Category":40,
"dtStart": "2025-10-06T00:00:00",
"show": true
}
]
10 changes: 0 additions & 10 deletions v2/RSCGExamplesData/NoExample.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,16 +876,6 @@
"name":"https://github.com/pierre3/PlantUmlClassDiagramGenerator",
"why":"later"
},
{
"ID":226,
"name":"https://github.com/Hookyns/validly",
"why":"later"
},
{
"ID":228,
"name":"https://github.com/nuskey8/Csv-CSharp",
"why":"later"
},
{
"ID":230,
"name":"https://github.com/FoundatioFx/Foundatio.Mediator",
Expand Down
59 changes: 59 additions & 0 deletions v2/book/examples/validly.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

<h1>RSCG nr 236 : validly</h1>

<h2>Info</h2>
Nuget : <a href="https://www.nuget.org/packages/validly/" target="_blank">https://www.nuget.org/packages/validly/</a>

<p>You can find more details at : <a href="https://github.com/Hookyns/validly" target="_blank"> https://github.com/Hookyns/validly</a></p>

<p>Author :Roman Jambor</p>

<p>Source: <a href="https://github.com/Hookyns/validly" target="_blank">https://github.com/Hookyns/validly</a> </p>

<h2>About</h2>

Generates validation code for C# classes based on attributes.

<h2>
How to use
</h2>
<h3>
Add reference to the <a href="https://www.nuget.org/packages/validly/" target="_blank">validly</a> in the csproj
</h3>
<img src="images/validly/valid.csproj.png" width="580" height="580" />

<h3>This was for me the <b>starting</b> code</h3>

<br />
I have <b>coded</b> the file Program.cs
<br />
<img src="images/validly/csFiles/Program.cs.png" width="580" height="580" />
<hr />

<br />
I have <b>coded</b> the file Person.cs
<br />
<img src="images/validly/csFiles/Person.cs.png" width="580" height="580" />
<hr />
<h3>And here are the <i>generated</i> files</h3>

<br />
The file <i>generated</i> is Person.Validator.g.cs
<br />
<img src="images/validly/generated/Person.Validator.g.cs.png" width="580" height="580" />

<p>
You can download the code and this page as pdf from
<a target="_blank" href='https://ignatandrei.github.io/RSCG_Examples/v2/docs/validly'>
https://ignatandrei.github.io/RSCG_Examples/v2/docs/validly
</a>
</p>


<p>
You can see the whole list at
<a target="_blank" href='https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG'>
https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG
</a>
</p>

6 changes: 5 additions & 1 deletion v2/book/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</head>
<body>
<h1>
This is the list of 235 RSCG with examples =>
This is the list of 236 RSCG with examples =>
</h1>

<table >
Expand Down Expand Up @@ -966,6 +966,10 @@ <h1>
<td>235</td>
<td><a href="examples/Csvcsharp.html">Csvcsharp</a></td>
</tr>
<tr>
<td>236</td>
<td><a href="examples/validly.html">validly</a></td>
</tr>
</table>


Expand Down
1 change: 1 addition & 0 deletions v2/book/pandocHTML.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ input-files:
- examples/VYaml.html
- examples/RapidEnum.html
- examples/Csvcsharp.html
- examples/validly.html

# or you may use input-file: with a single value
# defaults:
Expand Down
22 changes: 22 additions & 0 deletions v2/rscg_examples/validly/description.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"generator":{
"name":"validly",
"nuget":[
"https://www.nuget.org/packages/validly/"
],
"link":"https://github.com/Hookyns/validly",
"author":"Roman Jambor",
"source":"https://github.com/Hookyns/validly"
},
"data":{
"goodFor":["Generates validation code for C# classes based on attributes."],
"csprojDemo":"valid.csproj",
"csFiles":["Program.cs","Person.cs"],
"excludeDirectoryGenerated":[""],
"includeAdditionalFiles":[""]
},
"links":{
"blog":"",
"video":""
}
}
1 change: 1 addition & 0 deletions v2/rscg_examples/validly/nuget.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Powerful, efficient, and highly customizable validation library for .NET, leveraging the capabilities of C# Source Generators to provide compile-time validation logic generation.
121 changes: 121 additions & 0 deletions v2/rscg_examples/validly/readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Validly

[![NuGet](https://img.shields.io/nuget/v/Validly)](https://www.nuget.org/packages/Validly)
[![License MIT](https://img.shields.io/badge/License-MIT-brightgreen?style=flat-square)](https://opensource.org/licenses/MIT)
[![Support Ukraine](https://img.shields.io/badge/Support-Ukraine-FFDD00?labelColor=0057B7)](https://donate.redcross.org.uk/appeal/ukraine-crisis-appeal)<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->

This repository contains a powerful, efficient, and highly customizable validation library for .NET, leveraging the capabilities of C# Source Generators to provide compile-time validation logic generation. The library is designed to simplify model validation in .NET applications by automatically generating validation code based on attributes and custom rules, reducing runtime overhead and enhancing code maintainability.

## Key Features
- **Compile-Time Code Generation**: Uses C# Source Generators to create validation code at compile-time, eliminating the need for runtime reflection and improving performance.
- **Attribute-Based Validation**: Define validation rules using simple attributes directly on your models, allowing clear and maintainable validation rules.
- **Property and Object-Level Validation**: Supports validation of individual properties as well as the model as a whole, enabling both fine-grained and aggregate validations.
- **Customizable Validation Logic**: Extend the library with custom validation attributes and rules to meet unique validation requirements.
- **Detailed Validation Results**: Provides rich validation results, including per-property error messages and model-wide validation summaries.
- **Seamless Integration**: Designed to work smoothly in .NET applications, with support for dependency injection and easy configuration.

## Getting Started
To start using the library, add it to your project as a NuGet package. Decorate your model with `[Validatable]` attribute and properties with validation attributes and let the source generator handle the rest. Generated code will include optimized validation methods that you can call to validate instances of your models.

## Example Usage
Define validation rules using attributes on your model properties:

```csharp
[Validatable]
public partial class CreateUserRequest
{
[Required]
[MinLength(3)]
[MaxLength(100)]
public string Name { get; set; }

[Required]
[EmailAddress]
public string Email { get; set; }

[Range(18, 99)]
public int Age { get; set; }
}
```

Validate the model in your application code:
```csharp
app.MapPost("/users", async (CreateUserRequest request) =>
{
var validationResult = request.Validate(); // This method is generated by the source generator

if (!validationResult.IsSuccess)
{
return Results.BadRequest(validationResult);
}

// create user...
return Results.Created($"/users/{user.Id}");
});
```

## Installation
Install the package via NuGet:
```bash
dotnet add package Validly
```

Install the source generator package to enable compile-time validation code generation:
```bash
dotnet add package Validly.SourceGenerator
```

Install the package with default validators:
```bash
dotnet add package Validly.Extensions.Validators
```

## Why Validly? Why Attribute-Based Validation?
**Validly** was born out of the need for a simple, performant way to handle validations in applications, particularly when following Domain-Driven Design (DDD). In DDD, entities are responsible for their own validation. While validations on the API level are important, they cannot be the sole safeguard. The domain must validate entities independently, as the API is just one entry point to your system. Other sources, like background jobs or message queues, can also create or interact with domain objects.

Humans make mistakes, and developers are no exception. Relying solely on API-level validations is risky; you need a robust validation layer directly in your domain to ensure data integrity across all interactions.

**Why Not Existing Libraries?**

Libraries like FluentValidation are powerful, but they have limitations:

- Reflection-based design: While flexible, this approach bypasses static code analysis, making your code harder to refactor and less performant.
- Complexity: These libraries often require additional boilerplate code and are more suited to abstract validation pipelines, such as middleware in an API, than to domain entities.

Validly solves these issues by offering an attribute-based, source-generator-powered approach for validations. It combines simplicity, static analysis support, and high performance, making it an ideal choice for both API-level and domain-level validation.

**Why Attribute-Based Validation?**

Most validations are straightforward and can be expressed cleanly with attributes. For example, validating that a string is not empty or a number falls within a range shouldn’t require excessive boilerplate. Attributes allow you to express such requirements concisely and directly within your model.

Separating validations from the model may even be considered an anti-pattern or a violation of the Single Responsibility Principle. When validations are defined externally, it increases the likelihood of developer errors—such as forgetting to update validations when the model changes. By keeping validations close to the model, Validly ensures consistency, simplifies maintenance, and minimizes mistakes.

## Contributors

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hookyns"><img src="https://avatars.githubusercontent.com/u/2551259?v=4?s=100" width="100px;" alt="Roman Jámbor"/><br /><sub><b>Roman Jámbor</b></sub></a><br /><a href="https://github.com/Hookyns/validly/commits?author=Hookyns" title="Code">💻</a> <a href="#maintenance-Hookyns" title="Maintenance">🚧</a> <a href="https://github.com/Hookyns/validly/commits?author=Hookyns" title="Documentation">📖</a> <a href="https://github.com/Hookyns/validly/pulls?q=is%3Apr+reviewed-by%3AHookyns" title="Reviewed Pull Requests">👀</a> <a href="#example-Hookyns" title="Examples">💡</a> <a href="#ideas-Hookyns" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-Hookyns" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#question-Hookyns" title="Answering Questions">💬</a> <a href="https://github.com/Hookyns/validly/commits?author=Hookyns" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Whitepalko"><img src="https://avatars.githubusercontent.com/u/47061310?v=4?s=100" width="100px;" alt="Whitepalko"/><br /><sub><b>Whitepalko</b></sub></a><br /><a href="https://github.com/Hookyns/validly/commits?author=Whitepalko" title="Code">💻</a> <a href="#ideas-Whitepalko" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TallasDev"><img src="https://avatars.githubusercontent.com/u/30439223?v=4?s=100" width="100px;" alt="TallasDev"/><br /><sub><b>TallasDev</b></sub></a><br /><a href="#ideas-TallasDev" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/completezero"><img src="https://avatars.githubusercontent.com/u/15210432?v=4?s=100" width="100px;" alt="completezero"/><br /><sub><b>completezero</b></sub></a><br /><a href="https://github.com/Hookyns/validly/commits?author=completezero" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Stepami"><img src="https://avatars.githubusercontent.com/u/36167798?v=4?s=100" width="100px;" alt="Степан"/><br /><sub><b>Степан</b></sub></a><br /><a href="https://github.com/Hookyns/validly/commits?author=Stepami" title="Code">💻</a></td>
</tr>
</tbody>
</table>

<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

## License
This project is licensed under the MIT License.

---
This .NET validation library aims to streamline validation in .NET applications, leveraging modern C# features for performance and ease of use. It’s ideal for developers looking to minimize boilerplate code and maximize performance in their validation routines.
Loading