From b1234918fa7a2595d065df5220e036cc160accc1 Mon Sep 17 00:00:00 2001 From: Andrei Ignat Date: Sun, 15 Feb 2026 08:02:37 +0200 Subject: [PATCH 1/3] first --- v2/RSCGExamplesData/GeneratorDataRec.json | 6 +++++ v2/RSCGExamplesData/NoExample.json | 8 +++---- .../description.json | 22 +++++++++++++++++++ .../src/Attr.slnx | 3 +++ .../src/Attr/Attr.csproj | 17 ++++++++++++++ .../src/Attr/Person.cs | 18 +++++++++++++++ .../src/Attr/Program.cs | 6 +++++ .../src/Attr/Values.cs | 10 +++++++++ 8 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/description.json create mode 100644 v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr.slnx create mode 100644 v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Attr.csproj create mode 100644 v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Person.cs create mode 100644 v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Program.cs create mode 100644 v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/src/Attr/Values.cs 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/rscg_examples/Pekspro.DataAnnotationValuesExtractor/description.json b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/description.json new file mode 100644 index 000000000..ec5cfb769 --- /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":"", + "author":"", + "source":"" + }, + "data":{ + "goodFor":[""], + "csprojDemo":"Pekspro.DataAnnotationValuesExtractorDemo.csproj", + "csFiles":["Program.cs"], + "excludeDirectoryGenerated":[""], + "includeAdditionalFiles":[""] + }, + "links":{ + "blog":"", + "video":"" + } +} \ No newline at end of file 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 +{ +} From 6c8c6a5b97729d869a4a52ff8eaf4183110de13b Mon Sep 17 00:00:00 2001 From: Andrei Ignat Date: Sun, 15 Feb 2026 08:15:26 +0200 Subject: [PATCH 2/3] second --- README.md | 60 +- later.md | 12 +- ...Pekspro.DataAnnotationValuesExtractor.tour | 42 ++ v2/Generator/all.csv | 1 + .../description.json | 12 +- .../nuget.txt | 1 + .../readme.txt | 344 ++++++++++ .../video.json | 39 ++ v2/rscg_examples_site/docs/Authors/pekspro.md | 4 +- .../docs/Categories/EnhancementClass.md | 24 +- .../Categories/_PrimitiveEnhancementClass.mdx | 22 +- v2/rscg_examples_site/docs/NoExamples.md | 26 +- .../Pekspro.DataAnnotationValuesExtractor.md | 638 ++++++++++++++++++ .../docs/RSCG-Examples/index.md | 13 +- v2/rscg_examples_site/docs/about.md | 2 +- v2/rscg_examples_site/docs/indexRSCG.md | 5 +- .../src/components/HomepageFeatures/index.js | 2 +- .../static/exports/RSCG.json | 8 + .../static/exports/RSCG.xlsx | Bin 13558 -> 13609 bytes 19 files changed, 1181 insertions(+), 74 deletions(-) create mode 100644 v2/.tours/Pekspro.DataAnnotationValuesExtractor.tour create mode 100644 v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/nuget.txt create mode 100644 v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/readme.txt create mode 100644 v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/video.json create mode 100644 v2/rscg_examples_site/docs/RSCG-Examples/Pekspro.DataAnnotationValuesExtractor.md 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/rscg_examples/Pekspro.DataAnnotationValuesExtractor/description.json b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/description.json index ec5cfb769..5e67bd616 100644 --- a/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/description.json +++ b/v2/rscg_examples/Pekspro.DataAnnotationValuesExtractor/description.json @@ -4,14 +4,14 @@ "nuget":[ "https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/" ], - "link":"", - "author":"", - "source":"" + "link":"https://github.com/pekspro/DataAnnotationValuesExtractor", + "author":"Pekspro", + "source":"https://github.com/pekspro/DataAnnotationValuesExtractor" }, "data":{ - "goodFor":[""], - "csprojDemo":"Pekspro.DataAnnotationValuesExtractorDemo.csproj", - "csFiles":["Program.cs"], + "goodFor":["Generating code to extract values from data annotations in C#."], + "csprojDemo":"Attr.csproj", + "csFiles":["Program.cs","Person.cs","Values.cs"], "excludeDirectoryGenerated":[""], "includeAdditionalFiles":[""] }, 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 + +![Build +status](https://github.com/pekspro/DataAnnotationValuesExtractor/actions/workflows/build-and-test.yml/badge.svg) +[![NuGet](https://img.shields.io/nuget/v/Pekspro.DataAnnotationValuesExtractor.svg)](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/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) [![Nuget](https://img.shields.io/nuget/dt/Pekspro.BuildInformationGenerator?label=Pekspro.BuildInformationGenerator)](https://www.nuget.org/packages/Pekspro.BuildInformationGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/pekspro/BuildInformationGenerator?style=social) 2024-07-19 + 1 [Pekspro.DataAnnotationValuesExtractor](/docs/Pekspro.DataAnnotationValuesExtractor) [![Nuget](https://img.shields.io/nuget/dt/Pekspro.DataAnnotationValuesExtractor?label=Pekspro.DataAnnotationValuesExtractor)](https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/) ![GitHub Repo stars](https://img.shields.io/github/stars/pekspro/DataAnnotationValuesExtractor?style=social) 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) [![Nuget](https://img.shields.io/nuget/dt/Apparatus.AOT.Reflection?label=Apparatus.AOT.Reflection)](https://www.nuget.org/packages/Apparatus.AOT.Reflection/) ![GitHub Repo stars](https://img.shields.io/github/stars/byme8/Apparatus.AOT.Reflection?style=social) 2023-04-16 @@ -38,23 +38,25 @@ Number RSCG: 28 18 [OptionToStringGenerator](/docs/OptionToStringGenerator) [![Nuget](https://img.shields.io/nuget/dt/Seekatar.OptionToStringGenerator?label=Seekatar.OptionToStringGenerator)](https://www.nuget.org/packages/Seekatar.OptionToStringGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/Seekatar/OptionToStringGenerator?style=social) 2024-02-15 - 19 [Program](/docs/Program) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.AspNetCore.OpenApi?label=Microsoft.AspNetCore.OpenApi)](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/aspnetcore?style=social) 2025-11-06 + 19 [Pekspro.DataAnnotationValuesExtractor](/docs/Pekspro.DataAnnotationValuesExtractor) [![Nuget](https://img.shields.io/nuget/dt/Pekspro.DataAnnotationValuesExtractor?label=Pekspro.DataAnnotationValuesExtractor)](https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/) ![GitHub Repo stars](https://img.shields.io/github/stars/pekspro/DataAnnotationValuesExtractor?style=social) 2026-02-15 - 20 [QueryStringGenerator](/docs/QueryStringGenerator) [![Nuget](https://img.shields.io/nuget/dt/QueryStringGenerator?label=QueryStringGenerator)](https://www.nuget.org/packages/QueryStringGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/tparviainen/query-string-generator?style=social) 2024-11-07 + 20 [Program](/docs/Program) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.AspNetCore.OpenApi?label=Microsoft.AspNetCore.OpenApi)](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/aspnetcore?style=social) 2025-11-06 - 21 [RSCG_Decorator](/docs/RSCG_Decorator) [![Nuget](https://img.shields.io/nuget/dt/RSCG_Decorator?label=RSCG_Decorator)](https://www.nuget.org/packages/RSCG_Decorator/) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/RSCG_Decorator?style=social) 2023-09-30 + 21 [QueryStringGenerator](/docs/QueryStringGenerator) [![Nuget](https://img.shields.io/nuget/dt/QueryStringGenerator?label=QueryStringGenerator)](https://www.nuget.org/packages/QueryStringGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/tparviainen/query-string-generator?style=social) 2024-11-07 - 22 [RSCG_UtilityTypes](/docs/RSCG_UtilityTypes) [![Nuget](https://img.shields.io/nuget/dt/RSCG_UtilityTypes?label=RSCG_UtilityTypes)](https://www.nuget.org/packages/RSCG_UtilityTypes/)[![Nuget](https://img.shields.io/nuget/dt/RSCG_UtilityTypesCommon?label=RSCG_UtilityTypesCommon)](https://www.nuget.org/packages/RSCG_UtilityTypesCommon) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/RSCG_UtilityTypes?style=social) 2023-12-22 + 22 [RSCG_Decorator](/docs/RSCG_Decorator) [![Nuget](https://img.shields.io/nuget/dt/RSCG_Decorator?label=RSCG_Decorator)](https://www.nuget.org/packages/RSCG_Decorator/) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/RSCG_Decorator?style=social) 2023-09-30 - 23 [StaticReflection](/docs/StaticReflection) [![Nuget](https://img.shields.io/nuget/dt/FastStaticReflection?label=FastStaticReflection)](https://www.nuget.org/packages/FastStaticReflection/)[![Nuget](https://img.shields.io/nuget/dt/FastStaticReflection.CodeGen?label=FastStaticReflection.CodeGen)](https://www.nuget.org/packages/FastStaticReflection.CodeGen/) ![GitHub Repo stars](https://img.shields.io/github/stars/Cricle/StaticReflection?style=social) 2023-10-13 + 23 [RSCG_UtilityTypes](/docs/RSCG_UtilityTypes) [![Nuget](https://img.shields.io/nuget/dt/RSCG_UtilityTypes?label=RSCG_UtilityTypes)](https://www.nuget.org/packages/RSCG_UtilityTypes/)[![Nuget](https://img.shields.io/nuget/dt/RSCG_UtilityTypesCommon?label=RSCG_UtilityTypesCommon)](https://www.nuget.org/packages/RSCG_UtilityTypesCommon) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/RSCG_UtilityTypes?style=social) 2023-12-22 - 24 [SyncMethodGenerator](/docs/SyncMethodGenerator) [![Nuget](https://img.shields.io/nuget/dt/Zomp.SyncMethodGenerator?label=Zomp.SyncMethodGenerator)](https://www.nuget.org/packages/Zomp.SyncMethodGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/zompinc/sync-method-generator?style=social) 2023-08-14 + 24 [StaticReflection](/docs/StaticReflection) [![Nuget](https://img.shields.io/nuget/dt/FastStaticReflection?label=FastStaticReflection)](https://www.nuget.org/packages/FastStaticReflection/)[![Nuget](https://img.shields.io/nuget/dt/FastStaticReflection.CodeGen?label=FastStaticReflection.CodeGen)](https://www.nuget.org/packages/FastStaticReflection.CodeGen/) ![GitHub Repo stars](https://img.shields.io/github/stars/Cricle/StaticReflection?style=social) 2023-10-13 - 25 [System.Runtime.InteropServices](/docs/System.Runtime.InteropServices) [![Nuget](https://img.shields.io/nuget/dt/System.Runtime.InteropServices?label=System.Runtime.InteropServices)](https://www.nuget.org/packages/System.Runtime.InteropServices/) ![GitHub Repo stars](https://img.shields.io/www.nuget.org/stars/packages/System.Runtime.InteropServices?style=social) 2023-04-16 + 25 [SyncMethodGenerator](/docs/SyncMethodGenerator) [![Nuget](https://img.shields.io/nuget/dt/Zomp.SyncMethodGenerator?label=Zomp.SyncMethodGenerator)](https://www.nuget.org/packages/Zomp.SyncMethodGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/zompinc/sync-method-generator?style=social) 2023-08-14 - 26 [System.Text.RegularExpressions](/docs/System.Text.RegularExpressions) [![Nuget](https://img.shields.io/nuget/dt/System.Text.RegularExpressions?label=System.Text.RegularExpressions)](https://www.nuget.org/packages/System.Text.RegularExpressions/) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/runtime?style=social) 2023-04-16 + 26 [System.Runtime.InteropServices](/docs/System.Runtime.InteropServices) [![Nuget](https://img.shields.io/nuget/dt/System.Runtime.InteropServices?label=System.Runtime.InteropServices)](https://www.nuget.org/packages/System.Runtime.InteropServices/) ![GitHub Repo stars](https://img.shields.io/www.nuget.org/stars/packages/System.Runtime.InteropServices?style=social) 2023-04-16 - 27 [TelemetryLogging](/docs/TelemetryLogging) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.Extensions.Telemetry.Abstractions?label=Microsoft.Extensions.Telemetry.Abstractions)](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions/) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/extensions?style=social) 2023-11-30 + 27 [System.Text.RegularExpressions](/docs/System.Text.RegularExpressions) [![Nuget](https://img.shields.io/nuget/dt/System.Text.RegularExpressions?label=System.Text.RegularExpressions)](https://www.nuget.org/packages/System.Text.RegularExpressions/) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/runtime?style=social) 2023-04-16 - 28 [ThisClass](/docs/ThisClass) [![Nuget](https://img.shields.io/nuget/dt/ThisClass?label=ThisClass)](https://www.nuget.org/packages/ThisClass/) ![GitHub Repo stars](https://img.shields.io/github/stars/trympet/ThisClass?style=social) 2024-04-19 + 28 [TelemetryLogging](/docs/TelemetryLogging) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.Extensions.Telemetry.Abstractions?label=Microsoft.Extensions.Telemetry.Abstractions)](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions/) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/extensions?style=social) 2023-11-30 + + 29 [ThisClass](/docs/ThisClass) [![Nuget](https://img.shields.io/nuget/dt/ThisClass?label=ThisClass)](https://www.nuget.org/packages/ThisClass/) ![GitHub Repo stars](https://img.shields.io/github/stars/trympet/ThisClass?style=social) 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) [![Nuget](https://img.shields.io/nuget/dt/Seekatar.OptionToStringGenerator?label=Seekatar.OptionToStringGenerator)](https://www.nuget.org/packages/Seekatar.OptionToStringGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/Seekatar/OptionToStringGenerator?style=social) 2024-02-15 - 19 [Program](/docs/Program) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.AspNetCore.OpenApi?label=Microsoft.AspNetCore.OpenApi)](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/aspnetcore?style=social) 2025-11-06 + 19 [Pekspro.DataAnnotationValuesExtractor](/docs/Pekspro.DataAnnotationValuesExtractor) [![Nuget](https://img.shields.io/nuget/dt/Pekspro.DataAnnotationValuesExtractor?label=Pekspro.DataAnnotationValuesExtractor)](https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/) ![GitHub Repo stars](https://img.shields.io/github/stars/pekspro/DataAnnotationValuesExtractor?style=social) 2026-02-15 - 20 [QueryStringGenerator](/docs/QueryStringGenerator) [![Nuget](https://img.shields.io/nuget/dt/QueryStringGenerator?label=QueryStringGenerator)](https://www.nuget.org/packages/QueryStringGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/tparviainen/query-string-generator?style=social) 2024-11-07 + 20 [Program](/docs/Program) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.AspNetCore.OpenApi?label=Microsoft.AspNetCore.OpenApi)](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/aspnetcore?style=social) 2025-11-06 - 21 [RSCG_Decorator](/docs/RSCG_Decorator) [![Nuget](https://img.shields.io/nuget/dt/RSCG_Decorator?label=RSCG_Decorator)](https://www.nuget.org/packages/RSCG_Decorator/) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/RSCG_Decorator?style=social) 2023-09-30 + 21 [QueryStringGenerator](/docs/QueryStringGenerator) [![Nuget](https://img.shields.io/nuget/dt/QueryStringGenerator?label=QueryStringGenerator)](https://www.nuget.org/packages/QueryStringGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/tparviainen/query-string-generator?style=social) 2024-11-07 - 22 [RSCG_UtilityTypes](/docs/RSCG_UtilityTypes) [![Nuget](https://img.shields.io/nuget/dt/RSCG_UtilityTypes?label=RSCG_UtilityTypes)](https://www.nuget.org/packages/RSCG_UtilityTypes/)[![Nuget](https://img.shields.io/nuget/dt/RSCG_UtilityTypesCommon?label=RSCG_UtilityTypesCommon)](https://www.nuget.org/packages/RSCG_UtilityTypesCommon) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/RSCG_UtilityTypes?style=social) 2023-12-22 + 22 [RSCG_Decorator](/docs/RSCG_Decorator) [![Nuget](https://img.shields.io/nuget/dt/RSCG_Decorator?label=RSCG_Decorator)](https://www.nuget.org/packages/RSCG_Decorator/) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/RSCG_Decorator?style=social) 2023-09-30 - 23 [StaticReflection](/docs/StaticReflection) [![Nuget](https://img.shields.io/nuget/dt/FastStaticReflection?label=FastStaticReflection)](https://www.nuget.org/packages/FastStaticReflection/)[![Nuget](https://img.shields.io/nuget/dt/FastStaticReflection.CodeGen?label=FastStaticReflection.CodeGen)](https://www.nuget.org/packages/FastStaticReflection.CodeGen/) ![GitHub Repo stars](https://img.shields.io/github/stars/Cricle/StaticReflection?style=social) 2023-10-13 + 23 [RSCG_UtilityTypes](/docs/RSCG_UtilityTypes) [![Nuget](https://img.shields.io/nuget/dt/RSCG_UtilityTypes?label=RSCG_UtilityTypes)](https://www.nuget.org/packages/RSCG_UtilityTypes/)[![Nuget](https://img.shields.io/nuget/dt/RSCG_UtilityTypesCommon?label=RSCG_UtilityTypesCommon)](https://www.nuget.org/packages/RSCG_UtilityTypesCommon) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/RSCG_UtilityTypes?style=social) 2023-12-22 - 24 [SyncMethodGenerator](/docs/SyncMethodGenerator) [![Nuget](https://img.shields.io/nuget/dt/Zomp.SyncMethodGenerator?label=Zomp.SyncMethodGenerator)](https://www.nuget.org/packages/Zomp.SyncMethodGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/zompinc/sync-method-generator?style=social) 2023-08-14 + 24 [StaticReflection](/docs/StaticReflection) [![Nuget](https://img.shields.io/nuget/dt/FastStaticReflection?label=FastStaticReflection)](https://www.nuget.org/packages/FastStaticReflection/)[![Nuget](https://img.shields.io/nuget/dt/FastStaticReflection.CodeGen?label=FastStaticReflection.CodeGen)](https://www.nuget.org/packages/FastStaticReflection.CodeGen/) ![GitHub Repo stars](https://img.shields.io/github/stars/Cricle/StaticReflection?style=social) 2023-10-13 - 25 [System.Runtime.InteropServices](/docs/System.Runtime.InteropServices) [![Nuget](https://img.shields.io/nuget/dt/System.Runtime.InteropServices?label=System.Runtime.InteropServices)](https://www.nuget.org/packages/System.Runtime.InteropServices/) ![GitHub Repo stars](https://img.shields.io/www.nuget.org/stars/packages/System.Runtime.InteropServices?style=social) 2023-04-16 + 25 [SyncMethodGenerator](/docs/SyncMethodGenerator) [![Nuget](https://img.shields.io/nuget/dt/Zomp.SyncMethodGenerator?label=Zomp.SyncMethodGenerator)](https://www.nuget.org/packages/Zomp.SyncMethodGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/zompinc/sync-method-generator?style=social) 2023-08-14 - 26 [System.Text.RegularExpressions](/docs/System.Text.RegularExpressions) [![Nuget](https://img.shields.io/nuget/dt/System.Text.RegularExpressions?label=System.Text.RegularExpressions)](https://www.nuget.org/packages/System.Text.RegularExpressions/) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/runtime?style=social) 2023-04-16 + 26 [System.Runtime.InteropServices](/docs/System.Runtime.InteropServices) [![Nuget](https://img.shields.io/nuget/dt/System.Runtime.InteropServices?label=System.Runtime.InteropServices)](https://www.nuget.org/packages/System.Runtime.InteropServices/) ![GitHub Repo stars](https://img.shields.io/www.nuget.org/stars/packages/System.Runtime.InteropServices?style=social) 2023-04-16 - 27 [TelemetryLogging](/docs/TelemetryLogging) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.Extensions.Telemetry.Abstractions?label=Microsoft.Extensions.Telemetry.Abstractions)](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions/) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/extensions?style=social) 2023-11-30 + 27 [System.Text.RegularExpressions](/docs/System.Text.RegularExpressions) [![Nuget](https://img.shields.io/nuget/dt/System.Text.RegularExpressions?label=System.Text.RegularExpressions)](https://www.nuget.org/packages/System.Text.RegularExpressions/) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/runtime?style=social) 2023-04-16 - 28 [ThisClass](/docs/ThisClass) [![Nuget](https://img.shields.io/nuget/dt/ThisClass?label=ThisClass)](https://www.nuget.org/packages/ThisClass/) ![GitHub Repo stars](https://img.shields.io/github/stars/trympet/ThisClass?style=social) 2024-04-19 + 28 [TelemetryLogging](/docs/TelemetryLogging) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.Extensions.Telemetry.Abstractions?label=Microsoft.Extensions.Telemetry.Abstractions)](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions/) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/extensions?style=social) 2023-11-30 + + 29 [ThisClass](/docs/ThisClass) [![Nuget](https://img.shields.io/nuget/dt/ThisClass?label=ThisClass)](https://www.nuget.org/packages/ThisClass/) ![GitHub Repo stars](https://img.shields.io/github/stars/trympet/ThisClass?style=social) 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 +[![Nuget](https://img.shields.io/nuget/dt/Pekspro.DataAnnotationValuesExtractor?label=Pekspro.DataAnnotationValuesExtractor)](https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/) +[![GitHub last commit](https://img.shields.io/github/last-commit/pekspro/DataAnnotationValuesExtractor?label=updated)](https://github.com/pekspro/DataAnnotationValuesExtractor) +![GitHub Repo stars](https://img.shields.io/github/stars/pekspro/DataAnnotationValuesExtractor?style=social) + +## 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 +![Alt text](https://github.com/pekspro.png) +::: + +## Original Readme +:::note + +### DataAnnotationValuesExtractor + +![Build +status](https://github.com/pekspro/DataAnnotationValuesExtractor/actions/workflows/build-and-test.yml/badge.svg) +[![NuGet](https://img.shields.io/nuget/v/Pekspro.DataAnnotationValuesExtractor.svg)](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 5b5c8c091548c6a598d8caf0e41fc8dff5da1473..9ff50b7b0fb45db030c2a2a5301df366dfc2c7ed 100644 GIT binary patch delta 907 zcmeyCxiYIhz?+#xgn@yBgJHL$f6V-2JJ#%BU|>*UWMJS2(iJ)S<@rU~N%{HNdKI}j zz5U*NhYWaF*9%qhYjOmxxV4Fab7QM;%aw(KzA;A`t7;C_pU(S}6Z!en)dyCEM-NP^ zVVzva#>n4@Vos)Jm#wyj;=AUiwzeyiXC9?iLT*dup=9^hdn3Y7#4%W?lek;X2 z_l(ooSv73={U7?-C6i6_JmO`3{Se~3v2uo0adtJE;_IM)ON8ovT`NcR>8bdJPxBZV zHZwBrW8?#Q-C*5K6OJb|ZNdp|K=yd3!;+v=H3@b3lpraqn7vc_e? zw|dVX0&-KYt$+UN=Fg>(f7ZMb4gT|I|37}1ix|LR-zoiZmj*E0L71Ci^ILsEMgf!L z6k~H^Q$rKeG(!_3L&M2@hH{)B*Y1&PICX2XsiAuPLBGQWJZw%W8Xb@!V? zrMI|Su4Jy>>M2sa!B(1Gt}|Rgp(U)7S=?`0{q6a7C*QBnpM5t~>Zoy=RFc7l6y6``jp6B_4P+Io1dJAN`qRJhIPqoMya@7dNf*I3`= zTe|9X^~`)pgZlKY$EFYCJ1+h{_|R_G=a$BLM(;}PdnOsFDm=_YxU=UPnoUF+xO+k8_wJC z(1E1Pn|kvf{sN}R2qp#wVIUptoS#>cnpd(p+DMQQ93lh+taGrpXB z!dONDHFB94B!IdRU=!2ii%e3J>GKnxC yat=5`fa>=GV^0cMA48boWIIEd$@5Kkzz$nyBF&UxG&#^nbn*ie0k+A;AjJSa`4}Vn~l5F@B3b26y=(o&_AR0 zQqI;Nhiv9cM;*AV{O5S{?Q2rEHd$JK`lu+h;`j_J?{s#?rLTkbFBSUtb!|SXXHUg9 zeA@W?AR}KZ(C1Dob|gR3VPL4cy!jN<4IR4+!S)Zbt)AHg3yOVRr*mFKCAP8Xr}v@u z4?0`wY{U7F>z{p;9;)5*==uMz@GxXx0GTwwQ#*RIxPdgId6G$*ftiItl7Xo~vWbbg zxsrmuosE7_YEEKFW`16AMrJ{=9l}W~vx=qJ%M|6SvQ;{C z*xlT2E;C=-QhY^UH0RoCTV9FFZZE3DBdiP^ox~SM7s-XVE4Q7oGRj=ER^D*gwe5En zS|xhdOna{S{XEZ%dZU{U-@VXxSzWq5Bl~Klif}#SXMy+3tO@L2bX__BnAN05CNbVN z75cVy-Rwf@Vw^B?{KrnCqq1_ogu9qpW-SCX2yxz|XDkrSRIC$BIzVFvOh-#3 Date: Sun, 15 Feb 2026 08:16:50 +0200 Subject: [PATCH 3/3] zip --- ...Pekspro.DataAnnotationValuesExtractor.html | 65 ++++++++++++++++++ v2/book/list.html | 6 +- v2/book/pandocHTML.yaml | 1 + .../Pekspro.DataAnnotationValuesExtractor.zip | Bin 0 -> 1428 bytes 4 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 v2/book/examples/Pekspro.DataAnnotationValuesExtractor.html create mode 100644 v2/rscg_examples_site/static/sources/Pekspro.DataAnnotationValuesExtractor.zip 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 +

+

+ Add reference to the Pekspro.DataAnnotationValuesExtractor in the csproj +

+ + +

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 =>

@@ -1050,6 +1050,10 @@

+ + + +
256 Sundew.DiscriminatedUnions
257Pekspro.DataAnnotationValuesExtractor
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_site/static/sources/Pekspro.DataAnnotationValuesExtractor.zip b/v2/rscg_examples_site/static/sources/Pekspro.DataAnnotationValuesExtractor.zip new file mode 100644 index 0000000000000000000000000000000000000000..9c88acb2dac734f4448b7f426365836094e2ee42 GIT binary patch literal 1428 zcmWIWW@Zs#U|`^2sJ8Qush=hVf0B*Fdy?;#lc|LJ% zMg|5~CI$upsL}dh^OK7Uit@8sCwcoFHV|mLzV?c>iy-$6mA7_Vk0`I*w7?}mODw0y zm{+YYw^x0Utu%Mv5zzvt5U=ip=Rg0&fBtg(cJ-vim5h!DV*`B;XKP-t*t{%bqMmZU zlbKXso8yIBItsbZGo(&OJ$dNsylvsrYfRqe6OL3DzKF@stzw*>$FWnPIdKD1$vpqVo=@Dln|J8%kIyXF za^RqXXSV0`W!r)n&p9#|H6=Y$KF%R+e_p;#@8J7e*F}r`&cAu`rOEn)3FEZ@kNlrv z=jERBd;ZDq+V*|1Z`qQ+X8-#rb)9$;G*T zXT1(P2<&73#OLfU=;iTMX^PUpOL1#FUi;eQTuzj|F}K%Rc!S9NGtK=^w0CrhEh&{? z+t>d-eV?73wc@r7H@g?je|9rI;vU=c4S`%bPlY6vO`i+hXLGw2dSjvXb2s0!GFN!k z1%FlEm-*;ZPp^BXZ*#!vV~tt9Ax3;s=`If#7qgt(>^#qL)^bbF*Jt+a@OPVWFvBrW zs>GFdPnx7Tk@-Y&f9(k`K-#?qoj8Kr#xF)xO@8TTv=0v=6`H$Zx+5_ z5G&=nH2?d*ll9ft+H}Pxzc!2syXvX7(JA-*q)T*amGkYERf2tPbT zit^Ko5_5q;GWYaGu0sX_3>R!K)Sp=4Jo&DlW5FsV3k!D3+lTMPo{YU%U;JV6A68e# z0^#l3_x%1Uw)j5dk9#>+Tzh^_Va`mkxXzw9l`)H1sy*jHe~^tQWB(tOROg4Me7o-a zObMHHDm3qBTw?r%1+Hy3#k#oKkLY}}k_uu^?CmkRxaa4`H5*ps8r7z8---Nx{`~a! z|B-S@I53xd_35l$4s`M_AcjX~SYl3TYBA8|rM-q+ha3c4f4A;EJdLwMT%ghI43YGN>951@<{x4_q?{8K1k>ICXcf6lmIPa*a%*FMJS$APx zfSY=%hUtd`QrR4Q8iHOWGhcZ}ZvJ)EH+j42Ol^C8HIJ$9?p)9`zfo+wfNOut@ngn$ zc1qucvNP__S@%Ci=a2-aq=;~?a$9bYg7<5& z2Hd3z&~HcpUdAA6!&YJ-^h5)hAZ^Iy2eNK#*#e<^3ou!Lb;C0WvR-Tn2%+~Fu=IlH kg(oLu&Df$4p}CP6su>=k0p6@^AbD0G)B-vygayO{09phH{r~^~ literal 0 HcmV?d00001