diff --git a/README.md b/README.md
index facaaafa2..6180d587a 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
-# RSCG - 256 Examples of Roslyn Source Code Generators / 16 created by Microsoft /
+# RSCG - 257 Examples of Roslyn Source Code Generators / 16 created by Microsoft /
-The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 256 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports.
+The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 257 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports.
This system serves as both a learning resource for .NET developers interested in source generators and an automated pipeline for maintaining up-to-date documentation about the RSCG ecosystem
-## Latest Update : 2026-02-14 => 14 February 2026
+## Latest Update : 2026-02-15 => 15 February 2026
If you want to see examples with code, please click ***[List V2](https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG)***
@@ -24,8 +24,30 @@ If you want to be notified each time I add a new RSCG example , please click htt
## Content
-Those are the 256 Roslyn Source Code Generators that I have tested you can see and download source code example.
+Those are the 257 Roslyn Source Code Generators that I have tested you can see and download source code example.
( including 16 from Microsoft )
+### 257. [Pekspro.DataAnnotationValuesExtractor](https://ignatandrei.github.io/RSCG_Examples/v2/docs/Pekspro.DataAnnotationValuesExtractor) , in the [EnhancementClass](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#enhancementclass) category
+
+Generated on : 2026-02-15 => 15 February 2026
+
+
+ Expand
+
+
+
+Author: Pekspro
+
+A source generator for creating constants from data annotations.
+
+Nuget: [https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/](https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/)
+
+
+Link: [https://ignatandrei.github.io/RSCG_Examples/v2/docs/Pekspro.DataAnnotationValuesExtractor](https://ignatandrei.github.io/RSCG_Examples/v2/docs/Pekspro.DataAnnotationValuesExtractor)
+
+Source: [https://github.com/pekspro/DataAnnotationValuesExtractor](https://github.com/pekspro/DataAnnotationValuesExtractor)
+
+
+
### 256. [Sundew.DiscriminatedUnions](https://ignatandrei.github.io/RSCG_Examples/v2/docs/Sundew.DiscriminatedUnions) , in the [FunctionalProgramming](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#functionalprogramming) category
Generated on : 2026-02-14 => 14 February 2026
@@ -6040,69 +6062,69 @@ Why I have not tested : issue opened
https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/GaoNian-NET/MapperToolkit&body=https://github.com/GaoNian-NET/MapperToolkit
-30) [https://github.com/IeuanWalker/MinimalApi.Endpoints/]( https://github.com/IeuanWalker/MinimalApi.Endpoints/) , https://github.com/IeuanWalker/MinimalApi.Endpoints/
+30) [https://github.com/gumbarros/EndpointHelpers]( https://github.com/gumbarros/EndpointHelpers) , https://github.com/gumbarros/EndpointHelpers
+
+Why I have not tested : later
+
+https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/gumbarros/EndpointHelpers&body=https://github.com/gumbarros/EndpointHelpers
+
+
+31) [https://github.com/IeuanWalker/MinimalApi.Endpoints/]( https://github.com/IeuanWalker/MinimalApi.Endpoints/) , https://github.com/IeuanWalker/MinimalApi.Endpoints/
Why I have not tested : later
https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/IeuanWalker/MinimalApi.Endpoints/&body=https://github.com/IeuanWalker/MinimalApi.Endpoints/
-31) [https://github.com/inputfalken/Dynatello]( https://github.com/inputfalken/Dynatello) , https://github.com/inputfalken/Dynatello
+32) [https://github.com/inputfalken/Dynatello]( https://github.com/inputfalken/Dynatello) , https://github.com/inputfalken/Dynatello
Why I have not tested : too complicated
https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/inputfalken/Dynatello&body=https://github.com/inputfalken/Dynatello
-32) [https://github.com/ionite34/MinimalApiMapper]( https://github.com/ionite34/MinimalApiMapper) , https://github.com/ionite34/MinimalApiMapper
+33) [https://github.com/ionite34/MinimalApiMapper]( https://github.com/ionite34/MinimalApiMapper) , https://github.com/ionite34/MinimalApiMapper
Why I have not tested : own idea where to generate files, so overwrites
https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/ionite34/MinimalApiMapper&body=https://github.com/ionite34/MinimalApiMapper
-33) [https://github.com/JasonBock/CslaGeneratorSerialization]( https://github.com/JasonBock/CslaGeneratorSerialization) , https://github.com/JasonBock/CslaGeneratorSerialization
+34) [https://github.com/JasonBock/CslaGeneratorSerialization]( https://github.com/JasonBock/CslaGeneratorSerialization) , https://github.com/JasonBock/CslaGeneratorSerialization
Why I have not tested : too complicated
https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/JasonBock/CslaGeneratorSerialization&body=https://github.com/JasonBock/CslaGeneratorSerialization
-34) [https://github.com/MoslemBenDhaou/DataSurface]( https://github.com/MoslemBenDhaou/DataSurface) , https://github.com/MoslemBenDhaou/DataSurface
+35) [https://github.com/MoslemBenDhaou/DataSurface]( https://github.com/MoslemBenDhaou/DataSurface) , https://github.com/MoslemBenDhaou/DataSurface
Why I have not tested : later
https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/MoslemBenDhaou/DataSurface&body=https://github.com/MoslemBenDhaou/DataSurface
-35) [https://github.com/mu-dawood/EasyValidate]( https://github.com/mu-dawood/EasyValidate) , https://github.com/mu-dawood/EasyValidate
+36) [https://github.com/mu-dawood/EasyValidate]( https://github.com/mu-dawood/EasyValidate) , https://github.com/mu-dawood/EasyValidate
Why I have not tested : later
https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/mu-dawood/EasyValidate&body=https://github.com/mu-dawood/EasyValidate
-36) [https://github.com/nuskey8/Csv-CSharp]( https://github.com/nuskey8/Csv-CSharp) , https://github.com/nuskey8/Csv-CSharp
+37) [https://github.com/nuskey8/Csv-CSharp]( https://github.com/nuskey8/Csv-CSharp) , https://github.com/nuskey8/Csv-CSharp
Why I have not tested : later
https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/nuskey8/Csv-CSharp&body=https://github.com/nuskey8/Csv-CSharp
-37) [https://github.com/OrgEleCho/EleCho.Internationalization]( https://github.com/OrgEleCho/EleCho.Internationalization) , https://github.com/OrgEleCho/EleCho.Internationalization
+38) [https://github.com/OrgEleCho/EleCho.Internationalization]( https://github.com/OrgEleCho/EleCho.Internationalization) , https://github.com/OrgEleCho/EleCho.Internationalization
Why I have not tested : issue opened
https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/OrgEleCho/EleCho.Internationalization&body=https://github.com/OrgEleCho/EleCho.Internationalization
-38) [https://github.com/pekspro/DataAnnotationValuesExtractor]( https://github.com/pekspro/DataAnnotationValuesExtractor) , https://github.com/pekspro/DataAnnotationValuesExtractor
-
-Why I have not tested : later
-
-https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/pekspro/DataAnnotationValuesExtractor&body=https://github.com/pekspro/DataAnnotationValuesExtractor
-
-
39) [https://github.com/pierre3/PlantUmlClassDiagramGenerator]( https://github.com/pierre3/PlantUmlClassDiagramGenerator) , https://github.com/pierre3/PlantUmlClassDiagramGenerator
Why I have not tested : later
diff --git a/later.md b/later.md
index c04831d49..2afd4de87 100644
--- a/later.md
+++ b/later.md
@@ -1,6 +1,6 @@
# Just later
-## Latest Update : 2026-02-14 => 14 February 2026
+## Latest Update : 2026-02-15 => 15 February 2026
@@ -74,31 +74,31 @@ Why I have not tested : later
-12) [https://github.com/IeuanWalker/MinimalApi.Endpoints/]( https://github.com/IeuanWalker/MinimalApi.Endpoints/) , https://github.com/IeuanWalker/MinimalApi.Endpoints/
+12) [https://github.com/gumbarros/EndpointHelpers]( https://github.com/gumbarros/EndpointHelpers) , https://github.com/gumbarros/EndpointHelpers
Why I have not tested : later
-13) [https://github.com/MoslemBenDhaou/DataSurface]( https://github.com/MoslemBenDhaou/DataSurface) , https://github.com/MoslemBenDhaou/DataSurface
+13) [https://github.com/IeuanWalker/MinimalApi.Endpoints/]( https://github.com/IeuanWalker/MinimalApi.Endpoints/) , https://github.com/IeuanWalker/MinimalApi.Endpoints/
Why I have not tested : later
-14) [https://github.com/mu-dawood/EasyValidate]( https://github.com/mu-dawood/EasyValidate) , https://github.com/mu-dawood/EasyValidate
+14) [https://github.com/MoslemBenDhaou/DataSurface]( https://github.com/MoslemBenDhaou/DataSurface) , https://github.com/MoslemBenDhaou/DataSurface
Why I have not tested : later
-15) [https://github.com/nuskey8/Csv-CSharp]( https://github.com/nuskey8/Csv-CSharp) , https://github.com/nuskey8/Csv-CSharp
+15) [https://github.com/mu-dawood/EasyValidate]( https://github.com/mu-dawood/EasyValidate) , https://github.com/mu-dawood/EasyValidate
Why I have not tested : later
-16) [https://github.com/pekspro/DataAnnotationValuesExtractor]( https://github.com/pekspro/DataAnnotationValuesExtractor) , https://github.com/pekspro/DataAnnotationValuesExtractor
+16) [https://github.com/nuskey8/Csv-CSharp]( https://github.com/nuskey8/Csv-CSharp) , https://github.com/nuskey8/Csv-CSharp
Why I have not tested : later
diff --git a/v2/.tours/Pekspro.DataAnnotationValuesExtractor.tour b/v2/.tours/Pekspro.DataAnnotationValuesExtractor.tour
new file mode 100644
index 000000000..5dc66ba47
--- /dev/null
+++ b/v2/.tours/Pekspro.DataAnnotationValuesExtractor.tour
@@ -0,0 +1,42 @@
+
+{
+ "$schema": "https://aka.ms/codetour-schema",
+ "title": "Pekspro.DataAnnotationValuesExtractor",
+ "steps":
+ [
+ {
+ "file": "rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Attr.csproj",
+ "description": "First, we add Nuget [Pekspro.DataAnnotationValuesExtractor](https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/) in csproj ",
+ "pattern": "Pekspro.DataAnnotationValuesExtractor"
+ }
+
+ ,{
+ "file": "rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Values.cs",
+ "description": "File Values.cs ",
+ "pattern": "this is the code"
+ }
+
+ ,{
+ "file": "rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Person.cs",
+ "description": "File Person.cs ",
+ "pattern": "this is the code"
+ }
+
+ ,{
+ "file": "rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Program.cs",
+ "description": "File Program.cs \r\n>> dotnet run --project rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Attr.csproj ",
+ "pattern": "this is the code"
+ }
+
+
+ ,{
+ "file": "rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/obj/GX/Pekspro.DataAnnotationValuesExtractor/Pekspro.DataAnnotationValuesExtractor.DataAnnotationValuesExtractor/Values.g.cs",
+ "description": "Generated File 1 from 1 : Values.g.cs ",
+ "line": 1
+ }
+
+ ],
+
+ "ref": "main"
+
+}
\ No newline at end of file
diff --git a/v2/Generator/all.csv b/v2/Generator/all.csv
index cf6e6e590..e992e99af 100644
--- a/v2/Generator/all.csv
+++ b/v2/Generator/all.csv
@@ -255,3 +255,4 @@ Nr,Key,Source,Category
254,ErrorOrX, https://github.com/ANcpLua/ErrorOrX,API
255,KnockOff, https://github.com/NeatooDotNet/KnockOff,Tests
256,Sundew.DiscriminatedUnions, https://github.com/sundews/Sundew.DiscriminatedUnions,FunctionalProgramming
+257,Pekspro.DataAnnotationValuesExtractor, https://github.com/pekspro/DataAnnotationValuesExtractor,EnhancementClass
diff --git a/v2/RSCGExamplesData/GeneratorDataRec.json b/v2/RSCGExamplesData/GeneratorDataRec.json
index 06f285fc0..2b41b3b6a 100644
--- a/v2/RSCGExamplesData/GeneratorDataRec.json
+++ b/v2/RSCGExamplesData/GeneratorDataRec.json
@@ -1552,5 +1552,11 @@
"Category": 10,
"dtStart": "2026-02-14T00:00:00",
"show": true
+ },
+ {
+ "ID":"Pekspro.DataAnnotationValuesExtractor",
+ "Category": 5,
+ "dtStart": "2026-02-15T00:00:00",
+ "show": true
}
]
\ No newline at end of file
diff --git a/v2/RSCGExamplesData/NoExample.json b/v2/RSCGExamplesData/NoExample.json
index 7e93ffa9e..de8916f6c 100644
--- a/v2/RSCGExamplesData/NoExample.json
+++ b/v2/RSCGExamplesData/NoExample.json
@@ -988,13 +988,13 @@
"why":"later"
},
{
- "ID":252,
- "name":"https://github.com/pekspro/DataAnnotationValuesExtractor",
+ "ID":253,
+ "name":"https://github.com/sebastienros/comptime",
"why":"later"
},
{
- "ID":253,
- "name":"https://github.com/sebastienros/comptime",
+ "ID":254,
+ "name":"https://github.com/gumbarros/EndpointHelpers",
"why":"later"
}
diff --git a/v2/book/examples/Pekspro.DataAnnotationValuesExtractor.html b/v2/book/examples/Pekspro.DataAnnotationValuesExtractor.html
new file mode 100644
index 000000000..a0fe87fa3
--- /dev/null
+++ b/v2/book/examples/Pekspro.DataAnnotationValuesExtractor.html
@@ -0,0 +1,65 @@
+
+
RSCG nr 257 : Pekspro.DataAnnotationValuesExtractor
+
+Info
+Nuget : https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/
+
+You can find more details at : https://github.com/pekspro/DataAnnotationValuesExtractor
+
+Author :Pekspro
+
+Source: https://github.com/pekspro/DataAnnotationValuesExtractor
+
+About
+
+Generating code to extract values from data annotations in C#.
+
+
+ How to use
+
+
+
+
+This was for me the starting code
+
+
+ I have coded the file Program.cs
+
+
+
+
+
+ I have coded the file Person.cs
+
+
+
+
+
+ I have coded the file Values.cs
+
+
+
+ And here are the generated files
+
+
+ The file generated is Values.g.cs
+
+
+
+
+ You can download the code and this page as pdf from
+
+ https://ignatandrei.github.io/RSCG_Examples/v2/docs/Pekspro.DataAnnotationValuesExtractor
+
+
+
+
+
+ You can see the whole list at
+
+ https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG
+
+
+
diff --git a/v2/book/list.html b/v2/book/list.html
index a77aa33b4..5cad34516 100644
--- a/v2/book/list.html
+++ b/v2/book/list.html
@@ -17,7 +17,7 @@
-This is the list of 256 RSCG with examples =>
+This is the list of 257 RSCG with examples =>
diff --git a/v2/book/pandocHTML.yaml b/v2/book/pandocHTML.yaml
index 53156b762..1f58034c7 100644
--- a/v2/book/pandocHTML.yaml
+++ b/v2/book/pandocHTML.yaml
@@ -270,6 +270,7 @@ input-files:
- examples/ErrorOrX.html
- examples/KnockOff.html
- examples/Sundew.DiscriminatedUnions.html
+- examples/Pekspro.DataAnnotationValuesExtractor.html
# or you may use input-file: with a single value
# defaults:
diff --git a/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/description.json b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/description.json
new file mode 100644
index 000000000..5e67bd616
--- /dev/null
+++ b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/description.json
@@ -0,0 +1,22 @@
+{
+ "generator":{
+ "name":"Pekspro.DataAnnotationValuesExtractor",
+ "nuget":[
+ "https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/"
+ ],
+ "link":"https://github.com/pekspro/DataAnnotationValuesExtractor",
+ "author":"Pekspro",
+ "source":"https://github.com/pekspro/DataAnnotationValuesExtractor"
+ },
+ "data":{
+ "goodFor":["Generating code to extract values from data annotations in C#."],
+ "csprojDemo":"Attr.csproj",
+ "csFiles":["Program.cs","Person.cs","Values.cs"],
+ "excludeDirectoryGenerated":[""],
+ "includeAdditionalFiles":[""]
+ },
+ "links":{
+ "blog":"",
+ "video":""
+ }
+}
\ No newline at end of file
diff --git a/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/nuget.txt b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/nuget.txt
new file mode 100644
index 000000000..fe889f580
--- /dev/null
+++ b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/nuget.txt
@@ -0,0 +1 @@
+A source generator for creating constants from data annotations.
\ No newline at end of file
diff --git a/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/readme.txt b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/readme.txt
new file mode 100644
index 000000000..74b55d3d1
--- /dev/null
+++ b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/readme.txt
@@ -0,0 +1,344 @@
+# DataAnnotationValuesExtractor
+
+
+[](https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/)
+
+A C# source generator that automatically extracts values from data annotation
+attributes and exposes them as strongly-typed constants. Access your
+`StringLength`, `Range`, `Required` and `Display` attribute values as constants
+in your classes.
+
+## Why Use This?
+
+When working with data annotations, you often need to reference validation
+constraints. A good way to solve it is to create constants. But it takes time to
+do and makes your data models harder to read. And it's harder when your models
+are auto generated like when you are scaffolding with Entity Framework.
+
+This source generator creates the constants automatically for you. If you have
+this model:
+
+```csharp
+public partial class Product
+{
+ [Required]
+ [StringLength(100)]
+ public string? Name { get; set; }
+
+ [Required]
+ [Range(0.01, 999999.99)]
+ public decimal Price { get; set; }
+}
+```
+
+Constants will be generated that you can access like this:
+
+```csharp
+// Name length constraints
+int maxNameLength = Product.Annotations.Name.MaximumLength; // 100
+bool nameRequired = Product.Annotations.Name.IsRequired; // true
+
+// Price constraints
+double minPrice = Product.Annotations.Price.Minimum; // 0.01
+double maxPrice = Product.Annotations.Price.Maximum; // 999999.99
+```
+
+## Usage Patterns
+
+There are two ways to configure DataAnnotationValuesExtractor depending on your
+needs:
+
+### 1. Direct Approach
+
+Apply `[DataAnnotationValues]` directly to each class you want to generate
+constants for:
+
+```csharp
+[DataAnnotationValues(StringLength = true, Range = true, Required = true, Display = true)]
+public partial class Product
+{
+ [Display(Name = "Product name")]
+ [Required]
+ [StringLength(100)]
+ public string? Name { get; set; }
+
+ [Display(Name = "Product price")]
+ [Required]
+ [Range(0.01, 999999.99)]
+ public decimal Price { get; set; }
+
+ public string? Sku { get; set; }
+}
+```
+
+### 2. Centralized Approach
+
+Create a dummy class and use the `DataAnnotationValuesToGenerate` attribute for
+each class you want to generate constants for. You can use the
+`DataAnnotationValuesConfiguration` attribute to configure what to be generated.
+
+```csharp
+using Pekspro.DataAnnotationValuesExtractor;
+
+[DataAnnotationValuesConfiguration(StringLength = true, Range = true, Required = true, Display = true)]
+[DataAnnotationValuesToGenerate(typeof(Customer))]
+[DataAnnotationValuesToGenerate(typeof(Order))]
+[DataAnnotationValuesToGenerate(typeof(Product))]
+partial class ValidationConstants
+{
+}
+```
+
+Your model classes remain unchanged.
+
+This approach is especially useful when working with auto-generated models, such
+as those created by Entity Framework scaffolding. If you do, and you have all
+your models in a folder, you can use this PowerShell script to generate the
+attributes for all models in that folder:
+
+```powershell
+Get-ChildItem -Filter '*.cs' |
+ Where-Object { -not ($_.BaseName -match '(?i)context') } |
+ ForEach-Object { "[DataAnnotationValuesToGenerate(typeof($($_.BaseName)))]" } |
+ Set-Clipboard
+```
+
+### Use the generated constants
+
+No matter which approach your are using, you can access generated constants like
+this:
+
+```csharp
+// Name
+int maxNameLength = Product.Annotations.Name.MaximumLength; // 100
+int minNameLength = Product.Annotations.Name.MinimumLength; // 0
+bool nameRequired = Product.Annotations.Name.IsRequired; // true
+string? nameDisplayName = Product.Annotations.Name.Display.Name; // Product name
+
+// Price
+double minPrice = Product.Annotations.Price.Minimum; // 0.01
+double maxPrice = Product.Annotations.Price.Maximum; // 999999.99
+bool priceRequired = Product.Annotations.Price.IsRequired;
+string? priceDisplayName = Product.Annotations.Price.Display.Name; // Price name
+
+// Sku
+bool skuRequired = Product.Annotations.Sku.IsRequired; // false
+```
+
+## Installation
+
+Add the package to your project:
+
+```bash
+dotnet add package Pekspro.DataAnnotationValuesExtractor
+```
+
+For optimal setup, configure the package reference in your `.csproj` to exclude
+it from your output assembly:
+
+```xml
+
+
+
+```
+
+**Why these attributes?**
+
+- `PrivateAssets="all"` - Projects referencing yours won't inherit this package,
+ they don't need it.
+- `ExcludeAssets="runtime"` - The attributes DLL won't be copied to your build
+ output, this is also not needed.
+
+## Configuration Options
+
+Both `[DataAnnotationValues]` and `[DataAnnotationValuesConfiguration]` support
+the following properties to control which constants are generated:
+
+| Property | Default | Generated Constants | Description |
+| -------------- | ------- | ---------------------------------------------------------------- | ----------------------------------------------- |
+| `StringLength` | `true` | `MaximumLength`, `MinimumLength` | Extract values from `[StringLength]` attribute. |
+| `Range` | `true` | `Minimum`, `Maximum`, `MinimumIsExclusive`, `MaximumIsExclusive` | Extract values from `[Range]` attribute. |
+| `Required` | `false` | `IsRequired` | Detect presence of `[Required]` attribute. |
+| `Display` | `false` | `Name`, `Description`, `ShortName` | Extract values from `[Display]` attribute. |
+
+Do you miss some annotations? Create an issue and let me know.
+
+## Viewing Generated Code
+
+There are two ways to inspect the generated source code:
+
+### Method 1: Go to Definition
+
+Right-click on your class name and select **Go to Definition** (F12). Visual
+Studio will show you the generated partial class.
+
+### Method 2: Output to File
+
+Add this to your `.csproj` file to save generated files to disk:
+
+```xml
+
+ true
+ $(BaseIntermediateOutputPath)\$(Configuration)\GeneratedFiles
+
+```
+
+Generated files will be saved to `obj\[Configuration]\GeneratedFiles\`
+directory.
+
+## Generated Code Example
+
+Given this input:
+
+```csharp
+[DataAnnotationValues(StringLength = true, Range = true, Required = true, Display = true)]
+public partial class Player
+{
+ [Display(Name = "Player name", ShortName ="Name", Description = "Name of player")]
+ [Required]
+ [StringLength(50)]
+ public string? Name { get; set; }
+
+ [StringLength(100, MinimumLength = 6)]
+ public string? Email { get; set; }
+
+ [Range(1, 100)]
+ public int Score { get; set; }
+}
+```
+
+The generator produces:
+
+```csharp
+public partial class Player
+{
+ ///
+ /// Data annotation values.
+ ///
+ public static class Annotations
+ {
+ ///
+ /// Data annotation values for Name.
+ ///
+ public static class Name
+ {
+ ///
+ /// Maximum length for Name.
+ ///
+ public const int MaximumLength = 50;
+
+ ///
+ /// Minimum length for Name.
+ ///
+ public const int MinimumLength = 0;
+
+ ///
+ /// Indicates whether Name is required.
+ ///
+ public const bool IsRequired = true;
+
+ ///
+ /// Display attribute values for Name.
+ ///
+ public static class Display
+ {
+ ///
+ /// Display name for Name.
+ ///
+ public const string? Name = "Player name";
+
+ ///
+ /// Short display name for Name.
+ ///
+ public const string? ShortName = "Name";
+
+ ///
+ /// Description for Name.
+ ///
+ public const string? Description = "Name of player";
+ }
+ }
+
+ ///
+ /// Data annotation values for Email.
+ ///
+ public static class Email
+ {
+ ///
+ /// Maximum length for Email.
+ ///
+ public const int MaximumLength = 100;
+
+ ///
+ /// Minimum length for Email.
+ ///
+ public const int MinimumLength = 6;
+
+ ///
+ /// Indicates whether Email is required.
+ ///
+ public const bool IsRequired = false;
+ }
+
+ ///
+ /// Data annotation values for Score.
+ ///
+ public static class Score
+ {
+ ///
+ /// Minimum value for Score.
+ ///
+ public const int Minimum = 1;
+
+ ///
+ /// Maximum value for Score.
+ ///
+ public const int Maximum = 100;
+
+ ///
+ /// Indicates whether the minimum value for Score is exclusive.
+ ///
+ public const bool MinimumIsExclusive = false;
+
+ ///
+ /// Indicates whether the maximum value for Score is exclusive.
+ ///
+ public const bool MaximumIsExclusive = false;
+
+ ///
+ /// Indicates whether Score is required.
+ ///
+ public const bool IsRequired = false;
+ }
+ }
+}
+```
+
+## Requirements
+
+- **.NET SDK 7.0 or later** - Required for the source generator to run
+- **Target Framework** - Can target .NET Core 3.1, .NET Standard 2.0, or any
+ later framework
+- **Partial Classes** - Generated code uses partial classes, so it must be in
+ the same assembly as your models
+
+> **Note:** You need .NET 7 SDK installed, but your project can target earlier
+> frameworks.
+
+## Contributing
+
+Contributions are welcome! Please feel free to submit issues or pull requests on
+[GitHub](https://github.com/pekspro/DataAnnotationValuesExtractor).
+
+## Credits
+
+This project is heavily inspired by the
+[NetEscapades.EnumExtractors](https://github.com/andrewlock/NetEscapades.EnumExtractors)
+project.
+
+## License
+
+This project is licensed under the MIT License. See the [LICENSE](LICENSE) file
+for details.
diff --git a/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr.slnx b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr.slnx
new file mode 100644
index 000000000..c31748f57
--- /dev/null
+++ b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr.slnx
@@ -0,0 +1,3 @@
+
+
+
diff --git a/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Attr.csproj b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Attr.csproj
new file mode 100644
index 000000000..a9fed26e1
--- /dev/null
+++ b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Attr.csproj
@@ -0,0 +1,17 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
+
+
+
+ true
+ $(BaseIntermediateOutputPath)\GX
+
+
diff --git a/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Person.cs b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Person.cs
new file mode 100644
index 000000000..8b6682400
--- /dev/null
+++ b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Person.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+namespace Attr;
+
+partial class Person
+{
+ [Display(Name = "First name")]
+ [Required]
+ [StringLength(100,MinimumLength =3)]
+ public string? FirstName { get; set; }
+
+ [Required]
+ [Range(18, 200)]
+ public int Age { get; set; }
+}
diff --git a/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Program.cs b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Program.cs
new file mode 100644
index 000000000..e414452f5
--- /dev/null
+++ b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Program.cs
@@ -0,0 +1,6 @@
+// See https://aka.ms/new-console-template for more information
+using Attr;
+
+Console.WriteLine(Person.Annotations.Age.Minimum);
+Console.WriteLine(Person.Annotations.FirstName.MinimumLength);
+Console.WriteLine(Person.Annotations.FirstName.MaximumLength);
diff --git a/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Values.cs b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Values.cs
new file mode 100644
index 000000000..189aa3bcd
--- /dev/null
+++ b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Values.cs
@@ -0,0 +1,10 @@
+using Pekspro.DataAnnotationValuesExtractor;
+
+namespace Attr;
+
+
+[DataAnnotationValuesOptions(StringLength = true, Range = true, Required = true, Display = true)]
+[DataAnnotationValuesToGenerate(typeof(Person))]
+partial class Values
+{
+}
diff --git a/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/video.json b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/video.json
new file mode 100644
index 000000000..edf03bb08
--- /dev/null
+++ b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/video.json
@@ -0,0 +1,39 @@
+{
+ "scriptName": "Pekspro.DataAnnotationValuesExtractor",
+ "steps":
+[
+ {"typeStep":"exec","arg":"clipchamp.exe launch"},
+ {"typeStep":"text","arg": "Welcome to Roslyn Examples"},
+ {"typeStep":"text","arg":"If you want to see more examples , see List Of RSCG"},
+ {"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG"},
+ {"typeStep":"text","arg": "My name is Andrei Ignat and I am deeply fond of Roslyn Source Code Generator. "},
+
+{"typeStep":"text","arg": "Today I will present Pekspro.DataAnnotationValuesExtractor . Generating code to extract values from data annotations in C#. ."},
+{"typeStep":"browser","arg":"https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/"},
+{"typeStep":"text","arg": "The whole example is here"},
+{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/Pekspro.DataAnnotationValuesExtractor"},
+{"typeStep":"text","arg": "You can download the code from here"},
+{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/Pekspro.DataAnnotationValuesExtractor#download-example-net--c-"},
+{"typeStep":"text","arg":"Here is the code downloaded "},
+{"typeStep":"exec","arg":"explorer.exe /select,D:\\gth\\RSCG_Examples\\v2\\Generator.sln"},
+{"typeStep":"text","arg": "So , let's start the project with Visual Studio Code "},
+{"typeStep":"stepvscode","arg": "-n D:\\gth\\RSCG_Examples\\v2"},
+
+{"typeStep":"text","arg": "To use it ,you will put the Nuget Pekspro.DataAnnotationValuesExtractor into the csproj "},
+
+{"typeStep":"stepvscode","arg": "-r -g D:\\gth\\RSCG_Examples\\v2\\rscg_examples\\Pekspro.DataAnnotationValuesExtractor\\src\\Attr\\Attr.csproj"},
+
+{"typeStep":"text","arg": "And now I will show you an example of using Pekspro.DataAnnotationValuesExtractor"},
+
+{"typeStep":"hide","arg": "now execute the tour in VSCode"},
+{"typeStep":"tour", "arg": "src/.tours/"},
+{"typeStep":"text","arg":" And I will execute the project"},
+{"typeStep":"showproj", "arg":"Attr.csproj"},
+{"typeStep":"text","arg":" This concludes the project"},
+{"typeStep":"waitseconds","arg":"30"},
+{"typeStep":"text","arg": "Remember, you can download the code from here"},
+{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/Pekspro.DataAnnotationValuesExtractor#download-example-net--c-",
+SpeakTest=" "},
+{"typeStep":"waitseconds","arg":"30"},
+]
+}
diff --git a/v2/rscg_examples_site/docs/Authors/pekspro.md b/v2/rscg_examples_site/docs/Authors/pekspro.md
index 66802f3b3..cb543af36 100644
--- a/v2/rscg_examples_site/docs/Authors/pekspro.md
+++ b/v2/rscg_examples_site/docs/Authors/pekspro.md
@@ -1,7 +1,7 @@
-# Author : pekspro
+# Author : Pekspro
Number RSCG: 1
- 1 [Pekspro.BuildInformationGenerator](/docs/Pekspro.BuildInformationGenerator) [](https://www.nuget.org/packages/Pekspro.BuildInformationGenerator/)  2024-07-19
+ 1 [Pekspro.DataAnnotationValuesExtractor](/docs/Pekspro.DataAnnotationValuesExtractor) [](https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/)  2026-02-15
diff --git a/v2/rscg_examples_site/docs/Categories/EnhancementClass.md b/v2/rscg_examples_site/docs/Categories/EnhancementClass.md
index 0498feec0..ef32cb39d 100644
--- a/v2/rscg_examples_site/docs/Categories/EnhancementClass.md
+++ b/v2/rscg_examples_site/docs/Categories/EnhancementClass.md
@@ -1,6 +1,6 @@
EnhancementClass
-Number RSCG: 28
+Number RSCG: 29
1 [ApparatusAOT](/docs/ApparatusAOT) [](https://www.nuget.org/packages/Apparatus.AOT.Reflection/)  2023-04-16
@@ -38,23 +38,25 @@ Number RSCG: 28
18 [OptionToStringGenerator](/docs/OptionToStringGenerator) [](https://www.nuget.org/packages/Seekatar.OptionToStringGenerator/)  2024-02-15
- 19 [Program](/docs/Program) [](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi)  2025-11-06
+ 19 [Pekspro.DataAnnotationValuesExtractor](/docs/Pekspro.DataAnnotationValuesExtractor) [](https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/)  2026-02-15
- 20 [QueryStringGenerator](/docs/QueryStringGenerator) [](https://www.nuget.org/packages/QueryStringGenerator/)  2024-11-07
+ 20 [Program](/docs/Program) [](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi)  2025-11-06
- 21 [RSCG_Decorator](/docs/RSCG_Decorator) [](https://www.nuget.org/packages/RSCG_Decorator/)  2023-09-30
+ 21 [QueryStringGenerator](/docs/QueryStringGenerator) [](https://www.nuget.org/packages/QueryStringGenerator/)  2024-11-07
- 22 [RSCG_UtilityTypes](/docs/RSCG_UtilityTypes) [](https://www.nuget.org/packages/RSCG_UtilityTypes/)[](https://www.nuget.org/packages/RSCG_UtilityTypesCommon)  2023-12-22
+ 22 [RSCG_Decorator](/docs/RSCG_Decorator) [](https://www.nuget.org/packages/RSCG_Decorator/)  2023-09-30
- 23 [StaticReflection](/docs/StaticReflection) [](https://www.nuget.org/packages/FastStaticReflection/)[](https://www.nuget.org/packages/FastStaticReflection.CodeGen/)  2023-10-13
+ 23 [RSCG_UtilityTypes](/docs/RSCG_UtilityTypes) [](https://www.nuget.org/packages/RSCG_UtilityTypes/)[](https://www.nuget.org/packages/RSCG_UtilityTypesCommon)  2023-12-22
- 24 [SyncMethodGenerator](/docs/SyncMethodGenerator) [](https://www.nuget.org/packages/Zomp.SyncMethodGenerator/)  2023-08-14
+ 24 [StaticReflection](/docs/StaticReflection) [](https://www.nuget.org/packages/FastStaticReflection/)[](https://www.nuget.org/packages/FastStaticReflection.CodeGen/)  2023-10-13
- 25 [System.Runtime.InteropServices](/docs/System.Runtime.InteropServices) [](https://www.nuget.org/packages/System.Runtime.InteropServices/)  2023-04-16
+ 25 [SyncMethodGenerator](/docs/SyncMethodGenerator) [](https://www.nuget.org/packages/Zomp.SyncMethodGenerator/)  2023-08-14
- 26 [System.Text.RegularExpressions](/docs/System.Text.RegularExpressions) [](https://www.nuget.org/packages/System.Text.RegularExpressions/)  2023-04-16
+ 26 [System.Runtime.InteropServices](/docs/System.Runtime.InteropServices) [](https://www.nuget.org/packages/System.Runtime.InteropServices/)  2023-04-16
- 27 [TelemetryLogging](/docs/TelemetryLogging) [](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions/)  2023-11-30
+ 27 [System.Text.RegularExpressions](/docs/System.Text.RegularExpressions) [](https://www.nuget.org/packages/System.Text.RegularExpressions/)  2023-04-16
- 28 [ThisClass](/docs/ThisClass) [](https://www.nuget.org/packages/ThisClass/)  2024-04-19
+ 28 [TelemetryLogging](/docs/TelemetryLogging) [](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions/)  2023-11-30
+
+ 29 [ThisClass](/docs/ThisClass) [](https://www.nuget.org/packages/ThisClass/)  2024-04-19
\ No newline at end of file
diff --git a/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementClass.mdx b/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementClass.mdx
index a7749049c..dad513a24 100644
--- a/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementClass.mdx
+++ b/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementClass.mdx
@@ -36,25 +36,27 @@
18 [OptionToStringGenerator](/docs/OptionToStringGenerator) [](https://www.nuget.org/packages/Seekatar.OptionToStringGenerator/)  2024-02-15
- 19 [Program](/docs/Program) [](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi)  2025-11-06
+ 19 [Pekspro.DataAnnotationValuesExtractor](/docs/Pekspro.DataAnnotationValuesExtractor) [](https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/)  2026-02-15
- 20 [QueryStringGenerator](/docs/QueryStringGenerator) [](https://www.nuget.org/packages/QueryStringGenerator/)  2024-11-07
+ 20 [Program](/docs/Program) [](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi)  2025-11-06
- 21 [RSCG_Decorator](/docs/RSCG_Decorator) [](https://www.nuget.org/packages/RSCG_Decorator/)  2023-09-30
+ 21 [QueryStringGenerator](/docs/QueryStringGenerator) [](https://www.nuget.org/packages/QueryStringGenerator/)  2024-11-07
- 22 [RSCG_UtilityTypes](/docs/RSCG_UtilityTypes) [](https://www.nuget.org/packages/RSCG_UtilityTypes/)[](https://www.nuget.org/packages/RSCG_UtilityTypesCommon)  2023-12-22
+ 22 [RSCG_Decorator](/docs/RSCG_Decorator) [](https://www.nuget.org/packages/RSCG_Decorator/)  2023-09-30
- 23 [StaticReflection](/docs/StaticReflection) [](https://www.nuget.org/packages/FastStaticReflection/)[](https://www.nuget.org/packages/FastStaticReflection.CodeGen/)  2023-10-13
+ 23 [RSCG_UtilityTypes](/docs/RSCG_UtilityTypes) [](https://www.nuget.org/packages/RSCG_UtilityTypes/)[](https://www.nuget.org/packages/RSCG_UtilityTypesCommon)  2023-12-22
- 24 [SyncMethodGenerator](/docs/SyncMethodGenerator) [](https://www.nuget.org/packages/Zomp.SyncMethodGenerator/)  2023-08-14
+ 24 [StaticReflection](/docs/StaticReflection) [](https://www.nuget.org/packages/FastStaticReflection/)[](https://www.nuget.org/packages/FastStaticReflection.CodeGen/)  2023-10-13
- 25 [System.Runtime.InteropServices](/docs/System.Runtime.InteropServices) [](https://www.nuget.org/packages/System.Runtime.InteropServices/)  2023-04-16
+ 25 [SyncMethodGenerator](/docs/SyncMethodGenerator) [](https://www.nuget.org/packages/Zomp.SyncMethodGenerator/)  2023-08-14
- 26 [System.Text.RegularExpressions](/docs/System.Text.RegularExpressions) [](https://www.nuget.org/packages/System.Text.RegularExpressions/)  2023-04-16
+ 26 [System.Runtime.InteropServices](/docs/System.Runtime.InteropServices) [](https://www.nuget.org/packages/System.Runtime.InteropServices/)  2023-04-16
- 27 [TelemetryLogging](/docs/TelemetryLogging) [](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions/)  2023-11-30
+ 27 [System.Text.RegularExpressions](/docs/System.Text.RegularExpressions) [](https://www.nuget.org/packages/System.Text.RegularExpressions/)  2023-04-16
- 28 [ThisClass](/docs/ThisClass) [](https://www.nuget.org/packages/ThisClass/)  2024-04-19
+ 28 [TelemetryLogging](/docs/TelemetryLogging) [](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions/)  2023-11-30
+
+ 29 [ThisClass](/docs/ThisClass) [](https://www.nuget.org/packages/ThisClass/)  2024-04-19
### See category
diff --git a/v2/rscg_examples_site/docs/NoExamples.md b/v2/rscg_examples_site/docs/NoExamples.md
index 054ed0601..6fe4a04d8 100644
--- a/v2/rscg_examples_site/docs/NoExamples.md
+++ b/v2/rscg_examples_site/docs/NoExamples.md
@@ -310,46 +310,46 @@ Why I have not put example: later
Why I have not put example: issue opened
-77)https://github.com/IeuanWalker/MinimalApi.Endpoints/ https://github.com/IeuanWalker/MinimalApi.Endpoints/
+77)https://github.com/gumbarros/EndpointHelpers https://github.com/gumbarros/EndpointHelpers
Why I have not put example: later
-78)https://github.com/inputfalken/Dynatello https://github.com/inputfalken/Dynatello
+78)https://github.com/IeuanWalker/MinimalApi.Endpoints/ https://github.com/IeuanWalker/MinimalApi.Endpoints/
+
+Why I have not put example: later
+
+79)https://github.com/inputfalken/Dynatello https://github.com/inputfalken/Dynatello
Why I have not put example: too complicated
-79)https://github.com/ionite34/MinimalApiMapper https://github.com/ionite34/MinimalApiMapper
+80)https://github.com/ionite34/MinimalApiMapper https://github.com/ionite34/MinimalApiMapper
Why I have not put example: own idea where to generate files, so overwrites
-80)https://github.com/JasonBock/CslaGeneratorSerialization https://github.com/JasonBock/CslaGeneratorSerialization
+81)https://github.com/JasonBock/CslaGeneratorSerialization https://github.com/JasonBock/CslaGeneratorSerialization
Why I have not put example: too complicated
-81)https://github.com/MoslemBenDhaou/DataSurface https://github.com/MoslemBenDhaou/DataSurface
+82)https://github.com/MoslemBenDhaou/DataSurface https://github.com/MoslemBenDhaou/DataSurface
Why I have not put example: later
-82)https://github.com/mu-dawood/EasyValidate https://github.com/mu-dawood/EasyValidate
+83)https://github.com/mu-dawood/EasyValidate https://github.com/mu-dawood/EasyValidate
Why I have not put example: later
-83)https://github.com/nevsnirG/MinimalRichDomain https://github.com/nevsnirG/MinimalRichDomain
+84)https://github.com/nevsnirG/MinimalRichDomain https://github.com/nevsnirG/MinimalRichDomain
Why I have not put example: old ISourceGenerator
-84)https://github.com/nuskey8/Csv-CSharp https://github.com/nuskey8/Csv-CSharp
+85)https://github.com/nuskey8/Csv-CSharp https://github.com/nuskey8/Csv-CSharp
Why I have not put example: later
-85)https://github.com/OrgEleCho/EleCho.Internationalization https://github.com/OrgEleCho/EleCho.Internationalization
+86)https://github.com/OrgEleCho/EleCho.Internationalization https://github.com/OrgEleCho/EleCho.Internationalization
Why I have not put example: issue opened
-86)https://github.com/pekspro/DataAnnotationValuesExtractor https://github.com/pekspro/DataAnnotationValuesExtractor
-
-Why I have not put example: later
-
87)https://github.com/pierre3/PlantUmlClassDiagramGenerator https://github.com/pierre3/PlantUmlClassDiagramGenerator
Why I have not put example: later
diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/Pekspro.DataAnnotationValuesExtractor.md b/v2/rscg_examples_site/docs/RSCG-Examples/Pekspro.DataAnnotationValuesExtractor.md
new file mode 100644
index 000000000..dd2b5c812
--- /dev/null
+++ b/v2/rscg_examples_site/docs/RSCG-Examples/Pekspro.DataAnnotationValuesExtractor.md
@@ -0,0 +1,638 @@
+---
+sidebar_position: 2570
+title: 257 - Pekspro.DataAnnotationValuesExtractor
+description: Generating code to extract values from data annotations in C#.
+slug: /Pekspro.DataAnnotationValuesExtractor
+---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+import TOCInline from '@theme/TOCInline';
+import SameCategory from '../Categories/_PrimitiveEnhancementClass.mdx';
+
+# Pekspro.DataAnnotationValuesExtractor by Pekspro
+
+
+
+
+## NuGet / site data
+[](https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/)
+[](https://github.com/pekspro/DataAnnotationValuesExtractor)
+
+
+## Details
+
+### Info
+:::info
+
+Name: **Pekspro.DataAnnotationValuesExtractor**
+
+A source generator for creating constants from data annotations.
+
+Author: Pekspro
+
+NuGet:
+*https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/*
+
+
+You can find more details at https://github.com/pekspro/DataAnnotationValuesExtractor
+
+Source: https://github.com/pekspro/DataAnnotationValuesExtractor
+
+:::
+
+### Author
+:::note
+Pekspro
+
+:::
+
+## Original Readme
+:::note
+
+### DataAnnotationValuesExtractor
+
+
+[](https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/)
+
+A C# source generator that automatically extracts values from data annotation
+attributes and exposes them as strongly-typed constants. Access your
+`StringLength`, `Range`, `Required` and `Display` attribute values as constants
+in your classes.
+
+###### Why Use This?
+
+When working with data annotations, you often need to reference validation
+constraints. A good way to solve it is to create constants. But it takes time to
+do and makes your data models harder to read. And it's harder when your models
+are auto generated like when you are scaffolding with Entity Framework.
+
+This source generator creates the constants automatically for you. If you have
+this model:
+
+```csharp
+public partial class Product
+{
+ [Required]
+ [StringLength(100)]
+ public string? Name \{ get; set; }
+
+ [Required]
+ [Range(0.01, 999999.99)]
+ public decimal Price \{ get; set; }
+}
+```
+
+Constants will be generated that you can access like this:
+
+```csharp
+// Name length constraints
+int maxNameLength = Product.Annotations.Name.MaximumLength; // 100
+bool nameRequired = Product.Annotations.Name.IsRequired; // true
+
+// Price constraints
+double minPrice = Product.Annotations.Price.Minimum; // 0.01
+double maxPrice = Product.Annotations.Price.Maximum; // 999999.99
+```
+
+###### Usage Patterns
+
+There are two ways to configure DataAnnotationValuesExtractor depending on your
+needs:
+
+######### 1. Direct Approach
+
+Apply `[DataAnnotationValues]` directly to each class you want to generate
+constants for:
+
+```csharp
+[DataAnnotationValues(StringLength = true, Range = true, Required = true, Display = true)]
+public partial class Product
+{
+ [Display(Name = "Product name")]
+ [Required]
+ [StringLength(100)]
+ public string? Name \{ get; set; }
+
+ [Display(Name = "Product price")]
+ [Required]
+ [Range(0.01, 999999.99)]
+ public decimal Price \{ get; set; }
+
+ public string? Sku \{ get; set; }
+}
+```
+
+######### 2. Centralized Approach
+
+Create a dummy class and use the `DataAnnotationValuesToGenerate` attribute for
+each class you want to generate constants for. You can use the
+`DataAnnotationValuesConfiguration` attribute to configure what to be generated.
+
+```csharp
+using Pekspro.DataAnnotationValuesExtractor;
+
+[DataAnnotationValuesConfiguration(StringLength = true, Range = true, Required = true, Display = true)]
+[DataAnnotationValuesToGenerate(typeof(Customer))]
+[DataAnnotationValuesToGenerate(typeof(Order))]
+[DataAnnotationValuesToGenerate(typeof(Product))]
+partial class ValidationConstants
+{
+}
+```
+
+Your model classes remain unchanged.
+
+This approach is especially useful when working with auto-generated models, such
+as those created by Entity Framework scaffolding. If you do, and you have all
+your models in a folder, you can use this PowerShell script to generate the
+attributes for all models in that folder:
+
+```powershell
+Get-ChildItem -Filter '*.cs' |
+ Where-Object \{ -not ($_.BaseName -match '(?i)context') \} |
+ ForEach-Object \{ "[DataAnnotationValuesToGenerate(typeof($($_.BaseName)))]" \} |
+ Set-Clipboard
+```
+
+######### Use the generated constants
+
+No matter which approach your are using, you can access generated constants like
+this:
+
+```csharp
+// Name
+int maxNameLength = Product.Annotations.Name.MaximumLength; // 100
+int minNameLength = Product.Annotations.Name.MinimumLength; // 0
+bool nameRequired = Product.Annotations.Name.IsRequired; // true
+string? nameDisplayName = Product.Annotations.Name.Display.Name; // Product name
+
+// Price
+double minPrice = Product.Annotations.Price.Minimum; // 0.01
+double maxPrice = Product.Annotations.Price.Maximum; // 999999.99
+bool priceRequired = Product.Annotations.Price.IsRequired;
+string? priceDisplayName = Product.Annotations.Price.Display.Name; // Price name
+
+// Sku
+bool skuRequired = Product.Annotations.Sku.IsRequired; // false
+```
+
+###### Installation
+
+Add the package to your project:
+
+```bash
+dotnet add package Pekspro.DataAnnotationValuesExtractor
+```
+
+For optimal setup, configure the package reference in your `.csproj` to exclude
+it from your output assembly:
+
+```xml
+
+
+
+```
+
+**Why these attributes?**
+
+- `PrivateAssets="all"` - Projects referencing yours won't inherit this package,
+ they don't need it.
+- `ExcludeAssets="runtime"` - The attributes DLL won't be copied to your build
+ output, this is also not needed.
+
+###### Configuration Options
+
+Both `[DataAnnotationValues]` and `[DataAnnotationValuesConfiguration]` support
+the following properties to control which constants are generated:
+
+| Property | Default | Generated Constants | Description |
+| -------------- | ------- | ---------------------------------------------------------------- | ----------------------------------------------- |
+| `StringLength` | `true` | `MaximumLength`, `MinimumLength` | Extract values from `[StringLength]` attribute. |
+| `Range` | `true` | `Minimum`, `Maximum`, `MinimumIsExclusive`, `MaximumIsExclusive` | Extract values from `[Range]` attribute. |
+| `Required` | `false` | `IsRequired` | Detect presence of `[Required]` attribute. |
+| `Display` | `false` | `Name`, `Description`, `ShortName` | Extract values from `[Display]` attribute. |
+
+Do you miss some annotations? Create an issue and let me know.
+
+###### Viewing Generated Code
+
+There are two ways to inspect the generated source code:
+
+######### Method 1: Go to Definition
+
+Right-click on your class name and select **Go to Definition** (F12). Visual
+Studio will show you the generated partial class.
+
+######### Method 2: Output to File
+
+Add this to your `.csproj` file to save generated files to disk:
+
+```xml
+
+ true
+ $(BaseIntermediateOutputPath)\$(Configuration)\GeneratedFiles
+
+```
+
+Generated files will be saved to `obj\[Configuration]\GeneratedFiles\`
+directory.
+
+###### Generated Code Example
+
+Given this input:
+
+```csharp
+[DataAnnotationValues(StringLength = true, Range = true, Required = true, Display = true)]
+public partial class Player
+{
+ [Display(Name = "Player name", ShortName ="Name", Description = "Name of player")]
+ [Required]
+ [StringLength(50)]
+ public string? Name \{ get; set; }
+
+ [StringLength(100, MinimumLength = 6)]
+ public string? Email \{ get; set; }
+
+ [Range(1, 100)]
+ public int Score \{ get; set; }
+}
+```
+
+The generator produces:
+
+```csharp
+public partial class Player
+{
+ ///
+ /// Data annotation values.
+ ///
+ public static class Annotations
+ {
+ ///
+ /// Data annotation values for Name.
+ ///
+ public static class Name
+ {
+ ///
+ /// Maximum length for Name.
+ ///
+ public const int MaximumLength = 50;
+
+ ///
+ /// Minimum length for Name.
+ ///
+ public const int MinimumLength = 0;
+
+ ///
+ /// Indicates whether Name is required.
+ ///
+ public const bool IsRequired = true;
+
+ ///
+ /// Display attribute values for Name.
+ ///
+ public static class Display
+ {
+ ///
+ /// Display name for Name.
+ ///
+ public const string? Name = "Player name";
+
+ ///
+ /// Short display name for Name.
+ ///
+ public const string? ShortName = "Name";
+
+ ///
+ /// Description for Name.
+ ///
+ public const string? Description = "Name of player";
+ }
+ }
+
+ ///
+ /// Data annotation values for Email.
+ ///
+ public static class Email
+ {
+ ///
+ /// Maximum length for Email.
+ ///
+ public const int MaximumLength = 100;
+
+ ///
+ /// Minimum length for Email.
+ ///
+ public const int MinimumLength = 6;
+
+ ///
+ /// Indicates whether Email is required.
+ ///
+ public const bool IsRequired = false;
+ }
+
+ ///
+ /// Data annotation values for Score.
+ ///
+ public static class Score
+ {
+ ///
+ /// Minimum value for Score.
+ ///
+ public const int Minimum = 1;
+
+ ///
+ /// Maximum value for Score.
+ ///
+ public const int Maximum = 100;
+
+ ///
+ /// Indicates whether the minimum value for Score is exclusive.
+ ///
+ public const bool MinimumIsExclusive = false;
+
+ ///
+ /// Indicates whether the maximum value for Score is exclusive.
+ ///
+ public const bool MaximumIsExclusive = false;
+
+ ///
+ /// Indicates whether Score is required.
+ ///
+ public const bool IsRequired = false;
+ }
+ }
+}
+```
+
+###### Requirements
+
+- **.NET SDK 7.0 or later** - Required for the source generator to run
+- **Target Framework** - Can target .NET Core 3.1, .NET Standard 2.0, or any
+ later framework
+- **Partial Classes** - Generated code uses partial classes, so it must be in
+ the same assembly as your models
+
+> **Note:** You need .NET 7 SDK installed, but your project can target earlier
+> frameworks.
+
+###### Contributing
+
+Contributions are welcome! Please feel free to submit issues or pull requests on
+[GitHub](https://github.com/pekspro/DataAnnotationValuesExtractor).
+
+###### Credits
+
+This project is heavily inspired by the
+[NetEscapades.EnumExtractors](https://github.com/andrewlock/NetEscapades.EnumExtractors)
+project.
+
+###### License
+
+This project is licensed under the MIT License. See the [LICENSE](https://github.com/pekspro/DataAnnotationValuesExtractor/LICENSE) file
+for details.
+
+
+:::
+
+### About
+:::note
+
+Generating code to extract values from data annotations in C#.
+
+
+:::
+
+## How to use
+
+### Example (source csproj, source files)
+
+
+
+
+
+This is the CSharp Project that references **Pekspro.DataAnnotationValuesExtractor**
+```xml showLineNumbers {11}
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
+
+
+
+ true
+ $(BaseIntermediateOutputPath)\GX
+
+
+
+```
+
+
+
+
+
+ This is the use of **Pekspro.DataAnnotationValuesExtractor** in *Program.cs*
+
+```csharp showLineNumbers
+// See https://aka.ms/new-console-template for more information
+using Attr;
+
+Console.WriteLine(Person.Annotations.Age.Minimum);
+Console.WriteLine(Person.Annotations.FirstName.MinimumLength);
+Console.WriteLine(Person.Annotations.FirstName.MaximumLength);
+
+```
+
+
+
+
+ This is the use of **Pekspro.DataAnnotationValuesExtractor** in *Person.cs*
+
+```csharp showLineNumbers
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+namespace Attr;
+
+partial class Person
+{
+ [Display(Name = "First name")]
+ [Required]
+ [StringLength(100,MinimumLength =3)]
+ public string? FirstName \{ get; set; }
+
+ [Required]
+ [Range(18, 200)]
+ public int Age \{ get; set; }
+}
+
+```
+
+
+
+
+ This is the use of **Pekspro.DataAnnotationValuesExtractor** in *Values.cs*
+
+```csharp showLineNumbers
+using Pekspro.DataAnnotationValuesExtractor;
+
+namespace Attr;
+
+
+[DataAnnotationValuesOptions(StringLength = true, Range = true, Required = true, Display = true)]
+[DataAnnotationValuesToGenerate(typeof(Person))]
+partial class Values
+{
+}
+
+```
+
+
+
+
+### Generated Files
+
+Those are taken from $(BaseIntermediateOutputPath)\GX
+
+
+
+
+```csharp showLineNumbers
+//---------------------------------------------------------------------------------------
+//
+// This code was generated by the Pekspro.DataAnnotationValuesExtractor source generator.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//---------------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace Attr
+{
+ ///
+ /// Data annotation values for Person.
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Pekspro.DataAnnotationValuesExtractor", "1.0.0")]
+ public partial class Person
+ {
+ ///
+ /// Data annotation values.
+ ///
+ public static class Annotations
+ {
+ ///
+ /// Data annotation values for FirstName.
+ ///
+ public static class FirstName
+ {
+ ///
+ /// Maximum length for FirstName.
+ ///
+ public const int MaximumLength = 100;
+
+ ///
+ /// Minimum length for FirstName.
+ ///
+ public const int MinimumLength = 3;
+
+ ///
+ /// Indicates whether FirstName is required.
+ ///
+ public const bool IsRequired = true;
+
+ ///
+ /// Display attribute values for FirstName.
+ ///
+ public static class Display
+ {
+ ///
+ /// Display name for FirstName.
+ ///
+ public const string? Name = "First name";
+
+ ///
+ /// Short display name for FirstName.
+ ///
+ public const string? ShortName = null;
+
+ ///
+ /// Description for FirstName.
+ ///
+ public const string? Description = null;
+ }
+ }
+
+ ///
+ /// Data annotation values for Age.
+ ///
+ public static class Age
+ {
+ ///
+ /// Minimum value for Age.
+ ///
+ public const int Minimum = 18;
+
+ ///
+ /// Maximum value for Age.
+ ///
+ public const int Maximum = 200;
+
+ ///
+ /// Indicates whether the minimum value for Age is exclusive.
+ ///
+ public const bool MinimumIsExclusive = false;
+
+ ///
+ /// Indicates whether the maximum value for Age is exclusive.
+ ///
+ public const bool MaximumIsExclusive = false;
+
+ ///
+ /// Indicates whether Age is required.
+ ///
+ public const bool IsRequired = true;
+ }
+ }
+ }
+}
+```
+
+
+
+
+## Useful
+
+### Download Example (.NET C#)
+
+:::tip
+
+[Download Example project Pekspro.DataAnnotationValuesExtractor ](/sources/Pekspro.DataAnnotationValuesExtractor.zip)
+
+:::
+
+
+### Share Pekspro.DataAnnotationValuesExtractor
+
+
+
+https://ignatandrei.github.io/RSCG_Examples/v2/docs/Pekspro.DataAnnotationValuesExtractor
+
+
+
diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/index.md b/v2/rscg_examples_site/docs/RSCG-Examples/index.md
index c7b8c6b00..b4a9b6e39 100644
--- a/v2/rscg_examples_site/docs/RSCG-Examples/index.md
+++ b/v2/rscg_examples_site/docs/RSCG-Examples/index.md
@@ -1,7 +1,7 @@
---
sidebar_position: 30
-title: 256 RSCG list by category
-description: 256 RSCG list by category
+title: 257 RSCG list by category
+description: 257 RSCG list by category
slug: /rscg-examples
---
@@ -524,7 +524,7 @@ import DocCardList from '@theme/DocCardList';
## EnhancementClass
- Expand EnhancementClass =>examples:28
+ Expand EnhancementClass =>examples:29
@@ -665,6 +665,11 @@ import DocCardList from '@theme/DocCardList';
[Program](/docs/Program)
+
+
+
+[Pekspro.DataAnnotationValuesExtractor](/docs/Pekspro.DataAnnotationValuesExtractor)
+
@@ -1820,6 +1825,8 @@ flowchart LR;
EnhancementClass--> Program((Program))
+ EnhancementClass--> Pekspro.DataAnnotationValuesExtractor((Pekspro.DataAnnotationValuesExtractor))
+
EnhancementProject--> ThisAssembly((ThisAssembly))
EnhancementProject--> RSCG_TimeBombComment((RSCG_TimeBombComment))
diff --git a/v2/rscg_examples_site/docs/about.md b/v2/rscg_examples_site/docs/about.md
index d16c4e722..701ef6830 100644
--- a/v2/rscg_examples_site/docs/about.md
+++ b/v2/rscg_examples_site/docs/about.md
@@ -6,7 +6,7 @@ title: About
## Content
You will find here code examples
-of 256 Roslyn Source Code Generator (RSCG)
+of 257 Roslyn Source Code Generator (RSCG)
that can be useful for you. That means, you will write more elegant and concise code - even if the generators code is not always nice to look.
## Are those examples ready for production?
diff --git a/v2/rscg_examples_site/docs/indexRSCG.md b/v2/rscg_examples_site/docs/indexRSCG.md
index 72222025b..57b374e66 100644
--- a/v2/rscg_examples_site/docs/indexRSCG.md
+++ b/v2/rscg_examples_site/docs/indexRSCG.md
@@ -7,9 +7,9 @@ slug: /List-of-RSCG
import useBaseUrl from '@docusaurus/useBaseUrl';
-## 256 RSCG with examples in descending chronological order
+## 257 RSCG with examples in descending chronological order
-This is the list of 256 ( 16 from Microsoft) RSCG with examples
+This is the list of 257 ( 16 from Microsoft) RSCG with examples
[See by category](/docs/rscg-examples) [See as json](/exports/RSCG.json) [See as Excel](/exports/RSCG.xlsx)
@@ -20,6 +20,7 @@ This is the list of 256 ( 16 from Microsoft) RSCG with examples
| No | Name | Date | Category |
| --------- | ----- | ---- | -------- |
+|257| [Pekspro.DataAnnotationValuesExtractor by Pekspro ](/docs/Pekspro.DataAnnotationValuesExtractor)|2026-02-15 => 15 February 2026 | [EnhancementClass](/docs/Categories/EnhancementClass) |
|256| [Sundew.DiscriminatedUnions by Kim Hugener Ohlsen ](/docs/Sundew.DiscriminatedUnions)|2026-02-14 => 14 February 2026 | [FunctionalProgramming](/docs/Categories/FunctionalProgramming) |
|255| [KnockOff by Keith Voels ](/docs/KnockOff)|2026-02-13 => 13 February 2026 | [Tests](/docs/Categories/Tests) |
|254| [ErrorOrX by Alexander Nachtmanns ](/docs/ErrorOrX)|2026-02-02 => 02 February 2026 | [API](/docs/Categories/API) |
diff --git a/v2/rscg_examples_site/src/components/HomepageFeatures/index.js b/v2/rscg_examples_site/src/components/HomepageFeatures/index.js
index b7a13c155..99fcbc2f0 100644
--- a/v2/rscg_examples_site/src/components/HomepageFeatures/index.js
+++ b/v2/rscg_examples_site/src/components/HomepageFeatures/index.js
@@ -4,7 +4,7 @@ import styles from './styles.module.css';
const FeatureList = [
{
-title: '256 Examples (16 from MSFT)',
+title: '257 Examples (16 from MSFT)',
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
description: (
<>
diff --git a/v2/rscg_examples_site/static/exports/RSCG.json b/v2/rscg_examples_site/static/exports/RSCG.json
index 6ee1a8f19..6b4aac306 100644
--- a/v2/rscg_examples_site/static/exports/RSCG.json
+++ b/v2/rscg_examples_site/static/exports/RSCG.json
@@ -2049,6 +2049,14 @@
"Source": "https://github.com/sundews/Sundew.DiscriminatedUnions",
"Category": "FunctionalProgramming",
"AddedOn": "2026-02-14T00:00:00"
+ },
+ {
+ "Name": "Pekspro.DataAnnotationValuesExtractor",
+ "Link": "https://ignatandrei.github.io/RSCG_Examples/v2/docs/Pekspro.DataAnnotationValuesExtractor",
+ "NuGet": "https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/",
+ "Source": "https://github.com/pekspro/DataAnnotationValuesExtractor",
+ "Category": "EnhancementClass",
+ "AddedOn": "2026-02-15T00:00:00"
}
]
}
\ No newline at end of file
diff --git a/v2/rscg_examples_site/static/exports/RSCG.xlsx b/v2/rscg_examples_site/static/exports/RSCG.xlsx
index 5b5c8c091..9ff50b7b0 100644
Binary files a/v2/rscg_examples_site/static/exports/RSCG.xlsx and b/v2/rscg_examples_site/static/exports/RSCG.xlsx differ
diff --git a/v2/rscg_examples_site/static/sources/Pekspro.DataAnnotationValuesExtractor.zip b/v2/rscg_examples_site/static/sources/Pekspro.DataAnnotationValuesExtractor.zip
new file mode 100644
index 000000000..9c88acb2d
Binary files /dev/null and b/v2/rscg_examples_site/static/sources/Pekspro.DataAnnotationValuesExtractor.zip differ