RSCG – Pekspro.DataAnnotationValuesExtractor
| name | Pekspro.DataAnnotationValuesExtractor |
| nuget | https://www.nuget.org/packages/Pekspro.DataAnnotationValuesExtractor/ |
| link | https://github.com/pekspro/DataAnnotationValuesExtractor |
| author | Pekspro |
Generates typed constants from DataAnnotations attributes ([Range], [StringLength], [Required], [Display])
at compile time — no reflection needed to read annotation values.
How to use
1. Decorate your model with standard DataAnnotations:
“`charp
partial class Person
{
[Display(Name = “First name”)]
[StringLength(100, MinimumLength = 3)]
public string? FirstName { get; set; }
[Range(18, 200)]
public int Age { get; set; }
}
“`
2. Declare a partial extractor class targeting the model:
“`charp
[DataAnnotationValuesOptions(StringLength = true, Range = true, Required = true, Display = true)]
[DataAnnotationValuesToGenerate(typeof(Person))]
partial class Values { }
“`
3. Access generated constants:
“`charp
Console.WriteLine(Person.Annotations.Age.Minimum); // 18
Console.WriteLine(Person.Annotations.FirstName.MinimumLength); // 3
Console.WriteLine(Person.Annotations.FirstName.MaximumLength); // 100
“`
You can use for Reusing DataAnnotation constraint values (min/max lengths, ranges) in UI or validation logic
without duplicating magic numbers or using reflection.
This is how you can use Pekspro.DataAnnotationValuesExtractor .
The code that you start with is
<project sdk="Microsoft.NET.Sdk">
<propertygroup>
<outputtype>Exe</outputtype>
<targetframework>net10.0</targetframework>
<implicitusings>enable</implicitusings>
<nullable>enable</nullable>
</propertygroup>
<itemgroup>
<packagereference version="1.0.0" include="Pekspro.DataAnnotationValuesExtractor">
</packagereference>
<propertygroup>
<emitcompilergeneratedfiles>true</emitcompilergeneratedfiles>
<compilergeneratedfilesoutputpath>$(BaseIntermediateOutputPath)\GX</compilergeneratedfilesoutputpath>
</propertygroup>
</itemgroup>
The code that you will use is
// 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);
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; }
}
using Pekspro.DataAnnotationValuesExtractor;
namespace Attr;
[DataAnnotationValuesOptions(StringLength = true, Range = true, Required = true, Display = true)]
[DataAnnotationValuesToGenerate(typeof(Person))]
partial class Values
{
}
The code that is generated is
//---------------------------------------------------------------------------------------
// <auto-generated>
// 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.
// </auto-generated>
//---------------------------------------------------------------------------------------
#nullable enable
namespace Attr
{
/// <summary>
/// Data annotation values for Person.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Pekspro.DataAnnotationValuesExtractor", "1.0.0")]
public partial class Person
{
/// <summary>
/// Data annotation values.
/// </summary>
public static class Annotations
{
/// <summary>
/// Data annotation values for FirstName.
/// </summary>
public static class FirstName
{
/// <summary>
/// Maximum length for FirstName.
/// </summary>
public const int MaximumLength = 100;
/// <summary>
/// Minimum length for FirstName.
/// </summary>
public const int MinimumLength = 3;
/// <summary>
/// Indicates whether FirstName is required.
/// </summary>
public const bool IsRequired = true;
/// <summary>
/// Display attribute values for FirstName.
/// </summary>
public static class Display
{
/// <summary>
/// Display name for FirstName.
/// </summary>
public const string? Name = "First name";
/// <summary>
/// Short display name for FirstName.
/// </summary>
public const string? ShortName = null;
/// <summary>
/// Description for FirstName.
/// </summary>
public const string? Description = null;
}
}
/// <summary>
/// Data annotation values for Age.
/// </summary>
public static class Age
{
/// <summary>
/// Minimum value for Age.
/// </summary>
public const int Minimum = 18;
/// <summary>
/// Maximum value for Age.
/// </summary>
public const int Maximum = 200;
/// <summary>
/// Indicates whether the minimum value for Age is exclusive.
/// </summary>
public const bool MinimumIsExclusive = false;
/// <summary>
/// Indicates whether the maximum value for Age is exclusive.
/// </summary>
public const bool MaximumIsExclusive = false;
/// <summary>
/// Indicates whether Age is required.
/// </summary>
public const bool IsRequired = true;
}
}
}
}
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/Pekspro.DataAnnotationValuesExtractor