FractalDataWorks.EnhancedEnums 0.1.6-alpha-g42103babd5

This is a prerelease version of FractalDataWorks.EnhancedEnums.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package FractalDataWorks.EnhancedEnums --version 0.1.6-alpha-g42103babd5
                    
NuGet\Install-Package FractalDataWorks.EnhancedEnums -Version 0.1.6-alpha-g42103babd5
                    
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="FractalDataWorks.EnhancedEnums" Version="0.1.6-alpha-g42103babd5">
  <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="FractalDataWorks.EnhancedEnums" Version="0.1.6-alpha-g42103babd5" />
                    
Directory.Packages.props
<PackageReference Include="FractalDataWorks.EnhancedEnums">
  <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 FractalDataWorks.EnhancedEnums --version 0.1.6-alpha-g42103babd5
                    
#r "nuget: FractalDataWorks.EnhancedEnums, 0.1.6-alpha-g42103babd5"
                    
#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 FractalDataWorks.EnhancedEnums@0.1.6-alpha-g42103babd5
                    
#: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=FractalDataWorks.EnhancedEnums&version=0.1.6-alpha-g42103babd5&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=FractalDataWorks.EnhancedEnums&version=0.1.6-alpha-g42103babd5&prerelease
                    
Install as a Cake Tool

FractalDataWorks Enhanced Enums

Part of the FractalDataWorks toolkit.

Build Status

Master Build Develop Build

Release Status

GitHub release (latest by date) GitHub release (latest by date including pre-releases)

Package Status

Nuget GitHub Packages

License

License

Advanced enumeration system with source generation for .NET applications.

Overview

FractalDataWorks Enhanced Enums provides a powerful alternative to standard C# enums, offering:

  • Type-safe enumeration patterns with compile-time validation
  • Source generation for boilerplate code reduction
  • Efficient lookup capabilities for value retrieval
  • Rich metadata support through attributes
  • Cross-assembly support for shared enum definitions

Installation

NuGet Package

dotnet add package FractalDataWorks.EnhancedEnums

Project Reference

When referencing the source generator as a project (e.g., for local development or benchmarks), you must configure it properly:

<ItemGroup>
  <ProjectReference Include="path\to\FractalDataWorks.EnhancedEnums.csproj" 
                    OutputItemType="Analyzer" 
                    ReferenceOutputAssembly="true" />
</ItemGroup>

Important:

  • OutputItemType="Analyzer" - Registers the project as a Roslyn analyzer/source generator
  • ReferenceOutputAssembly="true" - Ensures the attributes are available at runtime

Without proper configuration, the source generator won't run and the collection classes won't be generated.

Quick Start

Define an Enhanced Enum

using FractalDataWorks.EnhancedEnums.Attributes;

[EnhancedEnumOption]
public abstract class OrderStatus
{
    public abstract string Name { get; }
    public abstract string Description { get; }
    
    [EnumLookup]
    public abstract string Code { get; }
}

[EnumOption]
public class Pending : OrderStatus
{
    public override string Name => "Pending";
    public override string Description => "Order is pending processing";
    public override string Code => "PEND";
}

[EnumOption]
public class Processing : OrderStatus
{
    public override string Name => "Processing";
    public override string Description => "Order is being processed";
    public override string Code => "PROC";
}

[EnumOption]
public class Shipped : OrderStatus
{
    public override string Name => "Shipped";
    public override string Description => "Order has been shipped";
    public override string Code => "SHIP";
}

Use the Generated Collection

The source generator creates a static collection class with lookup methods:

// Get all values
foreach (var status in OrderStatuses.All)
{
    Console.WriteLine($"{status.Name}: {status.Description}");
}

// Lookup by name
var pending = OrderStatuses.GetByName("Pending");

// Lookup by custom property (marked with [EnumLookup])
var shipped = OrderStatuses.GetByCode("SHIP");

// Handle not found cases
var unknown = OrderStatuses.GetByName("Unknown"); // Returns null

Generated Code Example

The generator produces code like this:

public static class OrderStatuses
{
    private static readonly List<OrderStatus> _all = new List<OrderStatus>();
    
    static OrderStatuses()
    {
        _all.Add(new Pending());
        _all.Add(new Processing());
        _all.Add(new Shipped());
    }
    
    /// <summary>
    /// Gets all available OrderStatus values.
    /// </summary>
    public static ImmutableArray<OrderStatus> All => _all.ToImmutableArray();
    
    /// <summary>
    /// Gets the OrderStatus with the specified name.
    /// </summary>
    public static OrderStatus? GetByName(string name)
    {
        return _all.FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase));
    }
    
    /// <summary>
    /// Gets the OrderStatus with the specified Code.
    /// </summary>
    public static OrderStatus? GetByCode(string code)
    {
        return _all.FirstOrDefault(x => string.Equals(x.Code, code, StringComparison.OrdinalIgnoreCase));
    }
}

Features

Lookup Properties

Mark properties with [EnumLookup] to generate lookup methods:

[EnhancedEnumOption]
public abstract class Country
{
    public abstract string Name { get; }
    
    [EnumLookup]
    public abstract string IsoCode { get; }
    
    [EnumLookup]
    public abstract string Currency { get; }
}

[EnumOption]
public class UnitedStates : Country
{
    public override string Name => "United States";
    public override string IsoCode => "US";
    public override string Currency => "USD";
}

// Usage:
var country = Countries.GetByIsoCode("US");
var byCurrency = Countries.GetByCurrency("USD");

Custom Collection Names

[EnhancedEnumOption("MyStatuses")]
public abstract class StatusBase
{
    public abstract string Name { get; }
}

// Generates: MyStatuses.All, MyStatuses.GetByName()

String Comparison Options

[EnhancedEnumOption(NameComparison = StringComparison.Ordinal)]
public abstract class CaseSensitive
{
    public abstract string Name { get; }
}

Factory Pattern Support

[EnhancedEnumOption(UseFactory = true)]
public abstract class ConnectionType
{
    public abstract string Name { get; }
    
    // Factory method must be defined in base class
    public static ConnectionType Create(Type type)
    {
        return (ConnectionType)Activator.CreateInstance(type);
    }
}

Multiple Lookup Properties

[EnhancedEnumOption]
public abstract class Currency
{
    public abstract string Name { get; }
    
    [EnumLookup]
    public abstract string Code { get; }
    
    [EnumLookup]
    public abstract string Symbol { get; }
    
    [EnumLookup]
    public abstract int NumericCode { get; }
}

// Generates: GetByCode(), GetBySymbol(), GetByNumericCode()

Custom Lookup Method Names

[EnhancedEnumOption]
public abstract class UserRole
{
    public abstract string Name { get; }
    
    [EnumLookup(MethodName = "FindByLevel")]
    public abstract int PermissionLevel { get; }
}

// Generates: FindByLevel() instead of GetByPermissionLevel()

Best Practices

  1. Use descriptive names for enum options and properties
  2. Keep enums focused - avoid too many responsibilities
  3. Consider lookup patterns - mark frequently searched properties with [EnumLookup]
  4. Use factory pattern sparingly - only when you need fresh instances
  5. Document your enums with XML comments

Requirements

  • .NET Standard 2.0 or higher
  • C# 8.0 or higher for nullable reference types
  • Visual Studio 2022 or VS Code with C# extension for best experience

Migration from Traditional Enums

Before (Traditional Enum)

public enum OrderStatus
{
    Pending = 1,
    Processing = 2,
    Shipped = 3,
    Delivered = 4
}

After (Enhanced Enum)

[EnhancedEnumOption]
public abstract class OrderStatus
{
    public abstract string Name { get; }
    public abstract int Value { get; }
}

[EnumOption]
public class Pending : OrderStatus
{
    public override string Name => "Pending";
    public override int Value => 1;
}

[EnumOption]
public class Processing : OrderStatus
{
    public override string Name => "Processing";
    public override int Value => 2;
}

Advanced Usage

Cross-Assembly Support

Enhanced enums can be used across assembly boundaries by referencing the generated collection classes.

Nullable Properties

[EnhancedEnumOption]
public abstract class Config
{
    public abstract string Name { get; }
    
    [EnumLookup]
    public abstract string? OptionalKey { get; }
}

Complex Property Types

[EnhancedEnumOption]
public abstract class DateRange
{
    public abstract string Name { get; }
    
    [EnumLookup]
    public abstract DateTime StartDate { get; }
    
    [EnumLookup]
    public abstract Guid Id { get; }
}

Troubleshooting

Source Generator Not Running

If your enhanced enum collection classes are not being generated:

  1. Check Project Reference Configuration

    
    <ProjectReference Include="..\..\src\FractalDataWorks.EnhancedEnums\FractalDataWorks.EnhancedEnums.csproj" 
                      OutputItemType="Analyzer" 
                      ReferenceOutputAssembly="true" />
    
    
    <ProjectReference Include="..\..\src\FractalDataWorks.EnhancedEnums\FractalDataWorks.EnhancedEnums.csproj" />
    
  2. Enable Assembly Scanner Add to your AssemblyInfo.cs or any source file:

    using FractalDataWorks.SmartGenerators;
    
    [assembly: EnableAssemblyScanner]
    
  3. Check Build Output Look for warnings like:

    • CS8032: An instance of analyzer ... cannot be created
    • CS0103: The name 'YourEnums' does not exist in the current context

Common Issues

  • Missing Dependencies: The generator requires SmartGenerators dependencies. When using PackageReference, these are included automatically. With ProjectReference, you may need to ensure dependencies are available.
  • Case Sensitivity: By default, name lookups are case-insensitive. Use NameComparison attribute property to change this.
  • Nullable Reference Types: Generated code may produce warnings in projects with nullable reference types enabled. This is a known issue that doesn't affect functionality.

Contributing

See our Contributing Guide for details on how to contribute to this project.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (8)

Showing the top 5 NuGet packages that depend on FractalDataWorks.EnhancedEnums:

Package Downloads
FractalDataWorks.Connections

Package Description

FractalDataWorks.Services

Package Description

FractalDataWorks.Tools

Package Description

FractalDataWorks.Services.ExternalConnections.Abstractions

Package Description

FractalDataWorks.Services.SecretManagement.Abstractions

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.