ChaosForge.EnumContractMapper 0.1.1

dotnet add package ChaosForge.EnumContractMapper --version 0.1.1
                    
NuGet\Install-Package ChaosForge.EnumContractMapper -Version 0.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ChaosForge.EnumContractMapper" Version="0.1.1">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ChaosForge.EnumContractMapper" Version="0.1.1" />
                    
Directory.Packages.props
<PackageReference Include="ChaosForge.EnumContractMapper">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ChaosForge.EnumContractMapper --version 0.1.1
                    
#r "nuget: ChaosForge.EnumContractMapper, 0.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ChaosForge.EnumContractMapper@0.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ChaosForge.EnumContractMapper&version=0.1.1
                    
Install as a Cake Addin
#tool nuget:?package=ChaosForge.EnumContractMapper&version=0.1.1
                    
Install as a Cake Tool

ChaosForge.EnumContractMapper

A Roslyn source generator that uses [Description] as a unified enum contract across JSON serialization, EF Core persistence, and UI display. Zero reflection, zero runtime cost.

Why?

Every existing enum source generator operates on the enum member name. ChaosForge.EnumContractMapper uses [Description] as the wire format — the JSON over HTTP, the column in the database, and the API docs all agree on the same human-readable string. One attribute, every layer speaks the same language.

Installation

dotnet add package ChaosForge.EnumContractMapper

Usage

Add [Description] attributes to your enum members:

using System.ComponentModel;

public enum OrderStatus
{
    [Description("Pending Review")]
    PendingReview,

    [Description("Shipped to Customer")]
    Shipped,

    [Description("Cancelled by User")]
    Cancelled
}

The generator automatically produces:

Forward: enum to description string

string desc = OrderStatus.PendingReview.EnumDescription();
// "Pending Review"

Reverse: description string to enum

OrderStatus status = EnumContractMapper.OrderStatusFromDescription("Shipped to Customer");
// OrderStatus.Shipped

bool found = EnumContractMapper.TryOrderStatusFromDescription("Unknown", out var result);
// false

JSON serialization (System.Text.Json)

A JsonConverter<T> is generated per enum when System.Text.Json is referenced.

Register converters

Call AddEnumContractMapperConverters() once to enable flexible enum input/output for all enums:

builder.Services.ConfigureHttpJsonOptions(options =>
    options.SerializerOptions.AddEnumContractMapperConverters());

By default, enums are read flexibly (integer, description string, or member name) and written as integers.

[EnumDescription] — per-property description output

Use the [EnumDescription] attribute on specific properties to serialize as description strings instead of integers:

using ChaosForge.EnumContractMapper;

public class OrderResponse
{
    public OrderStatus Status { get; set; }       // output: 1 (integer)

    [EnumDescription]
    public Priority Priority { get; set; }        // output: "High Priority"
}
Flexible input

All three formats are accepted on input — no attribute needed:

{ "Status": 1 }
{ "Status": "Shipped to Customer" }
{ "Status": "Shipped" }

EF Core persistence

A ValueConverter<OrderStatus, string> is generated automatically when EF Core is referenced.

Apply to all enum properties (default)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.ApplyEnumContractMapperConverters();
}

Every enum property with a generated converter stores the description string in the database column instead of the integer value.

Opt-in per property with [EnumDescription]

Pass onlyAttributed: true to restrict conversion to entity properties marked with [EnumDescription]. Other enum properties persist as integers:

public class Order
{
    public int Id { get; set; }

    [EnumDescription]
    public OrderStatus Status { get; set; }   // stored as "Shipped to Customer"

    public Priority Priority { get; set; }    // stored as integer
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.ApplyEnumContractMapperConverters(onlyAttributed: true);
}

Compile-time diagnostics

ID Severity Description
ECM001 Error Enum member is missing [Description] (only on enums that have at least one)
ECM002 Error Duplicate description strings within an enum
ECM003 Warning [Flags] enums are not supported

Diagnostics only fire on enums that have opted in (at least one member has [Description]).

Override severity via .editorconfig

[*.cs]
dotnet_diagnostic.ECM001.severity = warning
dotnet_diagnostic.ECM002.severity = warning

How it works

  • Source generator runs at compile time — no runtime reflection
  • Conditional generation: JsonConverter only when System.Text.Json is referenced, ValueConverter only when EF Core is referenced
  • Single NuGet package, zero runtime dependencies

License

MIT

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.1 102 4/19/2026