EntityLengths.Generator by Taras Kovalenko
Nuget / site data
Details
Info
Name: EntityLengths.Generator
A C# source generator that automatically generates string length constants from Entity Framework configurations and data annotations.
Author: Taras Kovalenko
NuGet: https://www.nuget.org/packages/EntityLengths.Generator/
You can find more details at https://github.com/TarasKovalenko/EntityLengths.Generator/
Source : https://github.com/TarasKovalenko/EntityLengths.Generator/
Original Readme
EntityLengths.Generator
Goals
This library is a C# source generator designed to automatically generate string length constants from Entity Framework configurations and data annotations. By analyzing your model configurations, it eliminates the need for manual constant maintenance and reduces the risk of hardcoded length values across your application.
Terms of use
By using this project or its source code, for any purpose and in any shape or form, you grant your implicit agreement to all of the following statements:
- You unequivocally condemn Russia and its military aggression against Ukraine
- You recognize that Russia is an occupant that unlawfully invaded a sovereign state
- You agree that Russia is a terrorist state
- You fully support Ukraine's territorial integrity, including its claims over temporarily occupied territories
- You reject false narratives perpetuated by Russian state propaganda
To learn more about the war and how you can help, click here. Glory to Ukraine! 🇺🇦
Benefits
- Automatic Constant Generation: Automatically create string length constants based on your existing model configurations
- Reduced Redundancy: Eliminate manual maintenance of string length constants
- Compile-Time Safety: Generate constants at compile-time, ensuring type safety and preventing runtime errors
- Flexible Configuration: Supports multiple ways of defining string lengths across different .NET and Entity Framework patterns
Features
- Extracts string length configurations from:
- EF Core Fluent API configurations (
HasMaxLength
) - Data Annotations
[MaxLength]
[StringLength]
- Column type definitions
[Column(TypeName = "varchar(200)")]
[Column(TypeName = "nvarchar(200)")]
[Column(TypeName = "char(200)")]
- DbContext configurations (
OnModelCreating
)
- EF Core Fluent API configurations (
Installation
Install the library via NuGet Package Manager:
dotnet add package EntityLengths.Generator
Usage
The generator supports a few ways to define string lengths:
// Using MaxLength attribute
public class User
{
[MaxLength(50)]
public string Name { get; set; }
}
// Using StringLength attribute
public class User
{
[StringLength(50)]
public string Surname { get; set; }
}
// Using Column attribute
public class User
{
[Column(TypeName = "varchar(200)")]
public string Url { get; set; }
}
// Using Fluent API
public class UserConfiguration : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
builder.Property(p => p.Name)
.HasMaxLength(50);
}
}
// DbContext configuration
public class User
{
public required string Surname { get; set; }
}
public class UserDbContext : DbContext
{
public DbSet<User> Users { get; set; } = null!;
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().Property(b => b.Surname).HasMaxLength(150).IsRequired();
}
}
Generated output:
public static partial class EntityLengths
{
public static partial class User
{
public const int NameLength = 50;
public const int SurnameLength = 50;
public const int UrlLength = 200;
public const int SurnameLength = 200;
}
}
Configuration
There are ways to configure EntityLengths.Generator. Configuration values are needed during compile-time since this is a source generator:
- Assembly level attribute for configuration:
EntityLengthsGeneratorAttribute
[assembly: EntityLengthsGenerator(
GenerateDocumentation = true,
GeneratedClassName = "Constants",
LengthSuffix = "Length",
IncludeNamespaces = ["EntityLengths.Generator.Sample.Entities"],
ExcludeNamespaces = ["EntityLengths.Generator.Sample.Entities.Exclude"],
ScanNestedNamespaces = true,
ScanEntitySuffix = "User",
Namespace = "EntityLengths.Generator.Sample"
)]
GenerateDocumentation
- Generates XML documentation for the generated class. Default isfalse
.GeneratedClassName
- The name of the generated class. Default isEntityLengths
.LengthSuffix
- The suffix for the generated length constants. Default isLength
.IncludeNamespaces
- The namespaces to include in the generation process. Default isnull
.ExcludeNamespaces
- The namespaces to exclude from the generation process. Default isnull
.ScanNestedNamespaces
- Scans nested namespaces for entities. Default istrue
.ScanEntitySuffix
- The suffix for the entity classes to scan. Default isnull
.Namespace
- The namespace for the generated class. Default isnull
.
Generated output:
// <auto-generated/>
namespace EntityLengths.Generator.Sample;
/// <summary>
/// Contains generated string length constants for entity properties
/// </summary>
public static partial class Constants
{
/// <summary>
/// Length constants for ColumnTypeDefinitionUser
/// </summary>
public static partial class ColumnTypeDefinitionUser
{
/// <summary>
/// Maximum length for Name
/// </summary>
public const int NameLength = 200;
/// <summary>
/// Maximum length for Name1
/// </summary>
public const int Name1Length = 300;
/// <summary>
/// Maximum length for Name2
/// </summary>
public const int Name2Length = 400;
}
/// <summary>
/// Length constants for DataAnnotationUser
/// </summary>
public static partial class DataAnnotationUser
{
/// <summary>
/// Maximum length for Name
/// </summary>
public const int NameLength = 50;
/// <summary>
/// Maximum length for Surname
/// </summary>
public const int SurnameLength = 150;
}
/// <summary>
/// Length constants for DbContextUser
/// </summary>
public static partial class DbContextUser
{
/// <summary>
/// Maximum length for Name
/// </summary>
public const int NameLength = 50;
}
/// <summary>
/// Length constants for FluentUser
/// </summary>
public static partial class FluentUser
{
/// <summary>
/// Maximum length for Name
/// </summary>
public const int NameLength = 50;
}
}
About
Generating constants for max length for properties in entities
How to use
Example ( source csproj, source files )
- CSharp Project
- Program.cs
- globals.cs
- DotNetStatsContext.cs
This is the CSharp Project that references EntityLengths.Generator
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.1">
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.1" />
<PackageReference Include="EntityLengths.Generator" Version="1.0.3" />
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>
This is the use of EntityLengths.Generator in Program.cs
Console.WriteLine("Hello, World!");
DbContextOptionsBuilder<DotNetStatsContext> optionsBuilder = new();
optionsBuilder.UseInMemoryDatabase("StatsDatabase");
var cnt = new DotNetStatsContext(optionsBuilder.Options);
await cnt.Database.EnsureCreatedAsync();
Console.WriteLine("Database created");
Console.WriteLine(cnt.Projects.Count());
Console.WriteLine("The max length of the Name property of the Project entity is: " + Constants.Project.NameLength);
This is the use of EntityLengths.Generator in globals.cs
global using Microsoft.EntityFrameworkCore;
global using Stats.Database;
using EntityLengths.Generator.Configuration;
[assembly: EntityLengthsGenerator(
GenerateDocumentation = false,
GeneratedClassName = "Constants",
LengthSuffix = "Length",
IncludeNamespaces = ["Stats.Database"],
ExcludeNamespaces = [],
ScanNestedNamespaces = true,
ScanEntitySuffix = null,
Namespace = "Stats.Database"
)]
This is the use of EntityLengths.Generator in DotNetStatsContext.cs
namespace Stats.Database;
public partial class DotNetStatsContext : DbContext
{
internal DotNetStatsContext() : base() { }
public DotNetStatsContext(DbContextOptions<DotNetStatsContext> options)
: base(options)
{
}
public virtual DbSet<Project> Projects { get; set; }
public virtual DbSet<Star> Stars { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Project>(entity =>
{
entity.ToTable("Project");
entity.Property(e => e.Id).HasColumnName("ID");
entity.Property(e => e.Description).HasMaxLength(500);
entity.Property(e => e.Name).HasMaxLength(50);
entity.Property(e => e.SourceCodeUrl).HasMaxLength(50);
});
modelBuilder.Entity<Star>(entity =>
{
entity.Property(e => e.Id)
.HasColumnName("ID");
entity.Property(e => e.Idproject).HasColumnName("IDProject");
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
Generated Files
Those are taken from $(BaseIntermediateOutputPath)\GX
- Constants.g.cs
// <auto-generated/>
namespace Stats.Database;
public static partial class Constants
{
public static partial class Project
{
public const int DescriptionLength = 500;
public const int NameLength = 50;
public const int SourceCodeUrlLength = 50;
}
}
Usefull
Download Example (.NET C# )
Share EntityLengths.Generator
https://ignatandrei.github.io/RSCG_Examples/v2/docs/EntityLengths.Generator