FractalDataWorks.EnhancedEnums
0.1.28-alpha-g0f79040e54
See the version list below for details.
dotnet add package FractalDataWorks.EnhancedEnums --version 0.1.28-alpha-g0f79040e54
NuGet\Install-Package FractalDataWorks.EnhancedEnums -Version 0.1.28-alpha-g0f79040e54
<PackageReference Include="FractalDataWorks.EnhancedEnums" Version="0.1.28-alpha-g0f79040e54"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="FractalDataWorks.EnhancedEnums" Version="0.1.28-alpha-g0f79040e54" />
<PackageReference Include="FractalDataWorks.EnhancedEnums"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add FractalDataWorks.EnhancedEnums --version 0.1.28-alpha-g0f79040e54
#r "nuget: FractalDataWorks.EnhancedEnums, 0.1.28-alpha-g0f79040e54"
#:package FractalDataWorks.EnhancedEnums@0.1.28-alpha-g0f79040e54
#addin nuget:?package=FractalDataWorks.EnhancedEnums&version=0.1.28-alpha-g0f79040e54&prerelease
#tool nuget:?package=FractalDataWorks.EnhancedEnums&version=0.1.28-alpha-g0f79040e54&prerelease
FractalDataWorks Enhanced Enums
Advanced enumeration patterns with source generation for .NET applications.
Table of Contents
- Overview
- Installation
- Quick Start
- Features
- Performance
- Architecture
- API Reference
- Developer Guide
- Troubleshooting
- Contributing
Overview
FractalDataWorks Enhanced Enums provides a powerful alternative to standard C# enums with:
- Type-safe enumeration patterns with compile-time validation
- Source generation for zero boilerplate
- High-performance lookups with O(1) dictionary access
- Rich metadata support through properties and attributes
- Cross-assembly support for shared enum definitions
- Empty value pattern for "no selection" scenarios
- Static property accessors for direct enum value access
Installation
NuGet Package
dotnet add package FractalDataWorks.EnhancedEnums
Package Reference
<PackageReference Include="FractalDataWorks.EnhancedEnums" Version="*" />
Quick Start
1. Define Your Enhanced Enum
using FractalDataWorks.EnhancedEnums.Attributes;
[EnhancedEnumBase]
public abstract class OrderStatus
{
protected OrderStatus(string name, string description)
{
Name = name;
Description = description;
}
public string Name { get; }
public string Description { get; }
[EnumLookup]
public abstract string Code { get; }
}
[EnumOption]
public class Pending : OrderStatus
{
public Pending() : base("Pending", "Order is pending") { }
public override string Code => "PEND";
}
[EnumOption]
public class Shipped : OrderStatus
{
public Shipped() : base("Shipped", "Order has shipped") { }
public override string Code => "SHIP";
}
2. Use the Generated Collection
// 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
var shipped = OrderStatuses.GetByCode("SHIP");
// Direct static access
var status = OrderStatuses.Pending;
// Empty value
var none = OrderStatuses.Empty;
Features
Lookup Properties
Mark properties with [EnumLookup]
to generate efficient lookup methods:
[EnhancedEnumBase]
public abstract class Country
{
public abstract string Name { get; }
[EnumLookup]
public abstract string IsoCode { get; }
[EnumLookup(MethodName = "FindByCurrency")]
public abstract string Currency { get; }
}
// Usage
var us = Countries.GetByIsoCode("US");
var euroCountries = Countries.FindByCurrency("EUR");
Multiple Collections
Support multiple categorizations of the same base type:
[EnhancedEnumBase("ActiveStatuses")]
[EnhancedEnumBase("ErrorStatuses")]
public abstract class Status
{
public abstract string Name { get; }
}
[EnumOption(CollectionName = "ActiveStatuses")]
public class Running : Status { }
[EnumOption(CollectionName = "ErrorStatuses")]
public class Failed : Status { }
Interface-Based Return Types
Control return types for flexible hierarchies:
public interface IOrderStatus : IEnhancedEnumOption
{
string Description { get; }
}
[EnhancedEnumBase(ReturnType = "IOrderStatus")]
public abstract class OrderStatus : IOrderStatus
{
public abstract int Id { get; }
public abstract string Name { get; }
public abstract string Description { get; }
}
Cross-Assembly Support (Service Type Pattern)
Enhanced Enums fully supports the Service Type Pattern, allowing enum options to be discovered from multiple assemblies at compile time. This enables plugin architectures where new options can be added without modifying the base assembly.
How it works:
- Define your base enum type in a shared assembly with
[EnhancedEnumBase]
- Create option types in plugin assemblies with
[EnumOption]
- Plugin assemblies declare which assemblies can discover them using MSBuild properties
- The generator discovers ALL options at compile time and includes them in the generated collection
Configuration:
Plugin assemblies opt-in to discovery by declaring which assemblies can discover them in their .csproj
:
<PropertyGroup>
<IncludeInEnhancedEnumAssemblies>Main;FractalDataWorks.Services</IncludeInEnhancedEnumAssemblies>
</PropertyGroup>
<PropertyGroup>
<IncludeInEnhancedEnumAssemblies>MyApp.Core;MyApp.Services;MyApp.Web</IncludeInEnhancedEnumAssemblies>
</PropertyGroup>
Example - Plugin Architecture:
// Shared.dll - Base definition
[EnhancedEnumBase(IncludeReferencedAssemblies = true)]
public abstract class ServiceType
{
public abstract string Name { get; }
public abstract Type ImplementationType { get; }
}
// PluginA.dll - Plugin assembly (with IncludeInEnhancedEnumAssemblies=Main)
[EnumOption]
public class EmailService : ServiceType
{
public override string Name => "Email";
public override Type ImplementationType => typeof(SmtpEmailProvider);
}
// PluginB.dll - Another plugin (with IncludeInEnhancedEnumAssemblies=Main)
[EnumOption]
public class SmsService : ServiceType
{
public override string Name => "SMS";
public override Type ImplementationType => typeof(TwilioSmsProvider);
}
// Main.dll - Application using the services
// The generated ServiceTypes collection includes BOTH EmailService and SmsService!
var allServices = ServiceTypes.All; // Contains instances from both plugins
var emailService = ServiceTypes.GetByName("Email"); // Works!
Important:
- Plugin assemblies must explicitly opt-in to discovery via
<IncludeInEnhancedEnumAssemblies>
- The generator reads compiled assembly metadata at compile time (not runtime)
- Only assemblies that opt-in will have their enum options discovered
- This provides security by preventing unwanted assemblies from injecting options
Generic Enhanced Enums
Enhanced Enums now supports generic base types. Use the standard [EnhancedEnumBase]
attribute:
[EnhancedEnumBase]
public abstract class Container<T> where T : IDisposable
{
public abstract string Name { get; }
public abstract T Value { get; }
}
[EnumOption]
public class StringContainer : Container<string>
{
public override string Name => "String";
public override string Value => "Default";
}
[EnumOption]
public class StreamContainer : Container<FileStream>
{
public override string Name => "Stream";
public override FileStream Value => new FileStream(...);
}
The generator will:
- Extract type parameters and constraints
- Add required using statements from constraint types
- Generate type-safe collections
For generic types with complex constraints, you can specify a default return type:
[EnhancedEnumBase(
DefaultGenericReturnType = "IService",
DefaultGenericReturnTypeNamespace = "MyApp.Services")]
public abstract class ServiceType<T> where T : IService
{
public abstract string Name { get; }
}
Performance
Enhanced Enums are optimized for high-performance scenarios:
graph LR
A[Lookup Request] --> B{Lookup Type}
B -->|By Name| C[O(1) Dictionary]
B -->|By Property| D[O(1) Dictionary]
B -->|All Values| E[Cached Array]
C --> F[Zero Allocations]
D --> F
E --> F
Benchmark results show:
- 9x faster lookups compared to LINQ searches
- Zero allocations for all operations
- 35% additional improvement with .NET 8+ FrozenDictionary
Architecture
Source Generation Flow
sequenceDiagram
participant Code as Your Code
participant Attr as Attributes
participant Gen as Source Generator
participant Comp as Compiler
participant Out as Generated Code
Code->>Attr: Apply [EnhancedEnumBase]
Code->>Attr: Apply [EnumOption]
Attr->>Gen: Trigger generation
Gen->>Gen: Scan types
Gen->>Gen: Build collection
Gen->>Out: Generate static class
Out->>Comp: Compile together
Comp->>Code: Available at compile time
Generated Code Structure
classDiagram
class OrderStatus {
<<abstract>>
+string Name
+string Description
+string Code
}
class Pending {
+Pending()
+string Code = "PEND"
}
class Shipped {
+Shipped()
+string Code = "SHIP"
}
class OrderStatuses {
<<static>>
+ImmutableArray~OrderStatus~ All
+OrderStatus Empty
+OrderStatus Pending
+OrderStatus Shipped
+GetByName(string) OrderStatus?
+GetByCode(string) OrderStatus?
}
OrderStatus <|-- Pending
OrderStatus <|-- Shipped
OrderStatuses ..> OrderStatus : manages
API Reference
Attributes
[EnhancedEnumBase]
Marks a class as an enhanced enum base type.
[EnhancedEnumBase(
CollectionName = "MyStatuses", // Custom collection name
UseFactory = false, // Use factory pattern
NameComparison = StringComparison.OrdinalIgnoreCase, // Name comparison
IncludeReferencedAssemblies = false, // Cross-assembly scanning
ReturnType = "IMyStatus" // Custom return type
)]
[EnumOption]
Marks a class as an enum option.
[EnumOption(
Name = "CustomName", // Override display name
Order = 1, // Sort order
CollectionName = "MyCollection" // Target collection
)]
[EnumLookup]
Marks a property for lookup generation.
[EnumLookup(
MethodName = "FindByCode", // Custom method name
AllowMultiple = false, // Allow multiple matches
ReturnType = "IMyStatus" // Custom return type
)]
Generated Methods
Every generated collection includes:
ImmutableArray<T> All
- All enum valuesT Empty
- Empty/none valueT? GetByName(string name)
- Lookup by nameT? GetByXxx(...)
- Custom lookups for[EnumLookup]
properties- Static properties for each enum value
Developer Guide
Project Structure
FractalDataWorks.EnhancedEnums/
├── src/
│ ├── Attributes/ # Attribute definitions
│ ├── Analyzers/ # Roslyn analyzers
│ ├── Generators/ # Source generators
│ └── Models/ # Data models
├── tests/ # Unit tests
├── benchmarks/ # Performance benchmarks
└── samples/ # Example projects
Building from Source
# Clone repository
git clone https://github.com/FractalDataWorks/enhanced-enums.git
# Build
dotnet build
# Run tests
dotnet test
# Run benchmarks
dotnet run -c Release --project benchmarks/FractalDataWorks.EnhancedEnums.Benchmarks
Adding New Features
- Attributes: Define in
Attributes/
folder - Generation Logic: Modify
EnhancedEnumGenerator.cs
- Tests: Add to appropriate test project
- Documentation: Update this README
Testing Source Generators
[Fact]
public void GeneratesCollectionClass()
{
var source = @"
[EnhancedEnumBase]
public abstract class Status { }
[EnumOption]
public class Active : Status { }
";
var result = TestHelper.GenerateSource(source);
result.ShouldContain("public static class Statuses");
result.ShouldContain("public static Status Active");
}
Debugging Tips
Enable generator logging:
<PropertyGroup> <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> </PropertyGroup>
Check generated files: Look in
obj/Generated/
Use diagnostics: The generator reports informational diagnostics
Performance Considerations
- Use constructor patterns for better performance
- Avoid complex logic in enum constructors
- Consider .NET 8+ for FrozenDictionary benefits
- Cache enum instances - they're singletons
Troubleshooting
Source Generator Not Running
- Ensure proper package/project reference configuration
- Check for build errors preventing generation
- Clean and rebuild the solution
Missing Generated Code
- Verify attributes are applied correctly
- Check that base class is
abstract
- Ensure enum options are
public
and non-abstract
Performance Issues
- Review constructor complexity
- Check for excessive cross-assembly scanning
- Profile with included benchmarks
Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Setup
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
Code Style
- Follow existing patterns
- Add XML documentation
- Include unit tests
- Update benchmarks if needed
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Product | Versions 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. |
-
.NETStandard 2.0
- FractalDataWorks (>= 0.1.3-alpha-g1695442435)
- Microsoft.Bcl.HashCode (>= 6.0.0)
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.