EnumCraft.FeatureFlags
1.0.1
dotnet add package EnumCraft.FeatureFlags --version 1.0.1
NuGet\Install-Package EnumCraft.FeatureFlags -Version 1.0.1
<PackageReference Include="EnumCraft.FeatureFlags" Version="1.0.1" />
<PackageVersion Include="EnumCraft.FeatureFlags" Version="1.0.1" />
<PackageReference Include="EnumCraft.FeatureFlags" />
paket add EnumCraft.FeatureFlags --version 1.0.1
#r "nuget: EnumCraft.FeatureFlags, 1.0.1"
#:package EnumCraft.FeatureFlags@1.0.1
#addin nuget:?package=EnumCraft.FeatureFlags&version=1.0.1
#tool nuget:?package=EnumCraft.FeatureFlags&version=1.0.1
EnumCraft.FeatureFlags
Strongly-typed, provider-based feature flags built on EnumCraft.Core.
Overview
EnumCraft.FeatureFlags provides a clean, extensible feature flag abstraction for .NET applications. Define your own strongly-typed flag catalog, plug in a data provider, and get type-safe flag resolution with per-tenant override support.
This package is part of the EnumCraft ecosystem:
| Package | Description |
|---|---|
EnumCraft.Core |
Strongly-typed enums and flags (TypedEnum, TypedFlag) |
EnumCraft.Json |
JSON serialization extensions for TypedEnum and TypedFlag |
EnumCraft.FeatureFlags |
Feature flag abstraction and resolution engine (this package) |
EnumCraft.FeatureFlags.Json |
JSON file provider |
Installation
dotnet add package EnumCraft.FeatureFlags
dotnet add package EnumCraft.FeatureFlags.Json
Requirements
- .NET Standard 2.0+ or .NET 8.0+
EnumCraft.Core
Quick Start
1. Define your flag type
Each application defines its own concrete flag type. Each type has its own isolated provider, snapshot, and catalog.
using EnumCraft.FeatureFlags;
public sealed class AppFeatureFlag : FeatureFlag<AppFeatureFlag>
{
public static readonly AppFeatureFlag DarkMode = new( Guid.Parse("6255cf3c-2a18-4082-87f0-764bf76cc0f9"),
"Dark Mode",
nameof(DarkMode),
isActiveDefault: false );
public static readonly AppFeatureFlag NewDashboard = new( Guid.Parse("c473d35a-c391-444b-86a7-4aac8319db4e"),
"New Dashboard",
nameof(NewDashboard),
isActiveDefault: false );
public static readonly AppFeatureFlag BetaReporting = new( Guid.Parse("c74e06d8-1b6d-4614-8218-facb10da1ca6"),
"Beta Reporting",
nameof(BetaReporting),
isActiveDefault: false );
public static readonly AppFeatureFlag MaintenanceMode = new( Guid.Parse("aeba8047-b728-4e5b-8d66-f74f44a4bc76"),
"Maintenance Mode",
nameof(MaintenanceMode),
isActiveDefault: false );
private AppFeatureFlag(Guid id, string description, string code, bool isActiveDefault = false)
: base(id, description, code, isActiveDefault) { }
}
2. Configure at startup
Use Configure() to fail fast if the provider cannot initialize, or TryConfigure() for a safe wrapper that returns false with an error message instead of throwing an exception.
using EnumCraft.FeatureFlags.Json;
var options = new JsonFeatureFlagProviderOptions { DirectoryPath = AppDomain.CurrentDomain.BaseDirectory,
FileName = "AppFeatureFlag.json" };
// Fail-fast — throws exception if provider fails to initialize
AppFeatureFlag.Configure(new JsonFeatureFlagProvider(options));
// — or — safe wrapper
if(!AppFeatureFlag.TryConfigure(new JsonFeatureFlagProvider(options), out var error))
{
Console.WriteLine($"Failed to configure flags: {error}");
return;
}
Configure() may only be called once per flag type. Calling it a second time throws InvalidOperationException. Use TryConfigure() if you need to handle the already-configured case gracefully without an exception. Runtime provider swapping via Reconfigure() is not supported in v1.0.0 - a restart is required to change providers.
3. Use anywhere
// Global resolution
if(AppFeatureFlag.DarkMode.IsActive)
{
// enabled globally
}
// Per-tenant resolution (string tenant ID)
if(AppFeatureFlag.DarkMode["tenant-123"])
{
// enabled for this tenant
}
// Per-tenant resolution (int tenant ID)
if(AppFeatureFlag.DarkMode[1001])
{
// enabled for this tenant
}
// Full resolution chain (for diagnostics)
var resolution = AppFeatureFlag.DarkMode.Resolve(tenantId);
foreach(var r in resolution)
{
Console.WriteLine($"[{r.Priority}] {r.Source} → {r.Value}");
}
Resolution Order
For any flag lookup, the resolution priority is:
- Tenant override — per-tenant value from provider data, if present
- Global override — global value from provider data, if present
- Constructor default —
isActiveDefaultparameter value
FeatureFlagResolution
Resolve() returns IReadOnlyList<FeatureFlagResolution> - one entry per resolution source that participated. Each entry exposes the following.
| Property | Type | Description |
|---|---|---|
Description |
string? |
Description of the flag |
TenantID |
int |
Tenant ID used in the resolution (0 = global) |
Source |
FeatureFlagValueSource |
Which source determined the value |
Priority |
int |
Priority of this source (1 = highest) |
Value |
bool |
The value at this source |
FeatureFlagValueSource
| Value | Description |
|---|---|
Tenant |
Value came from a per-tenant override |
Global |
Value came from the global section |
Default |
Value came from the constructor isActiveDefault parameter |
Optional Logging
Set a logger on the flag type for diagnostic output. Falls back to NullLogger if not set.
using Microsoft.Extensions.Logging;
var logger = loggerFactory.CreateLogger<AppFeatureFlag>();
AppFeatureFlag.SetLogger(logger);
Implementing a Custom Provider
Implement IFeatureFlagProvider to load flag data from any source:
public class MyCustomProvider : IFeatureFlagProvider
{
public event EventHandler? Changed;
public bool Initialize(out string? error)
{
// load your data
error = null;
return true;
}
public FeatureFlagData GetSnapshot()
{
// return current data
return new FeatureFlagData();
}
public void Dispose() { }
}
IFeatureFlagProvider extends IDisposable - providers own their lifecycle and must clean up any watchers, timers, or connections in Dispose().
Framework Support
| Framework | Supported |
|---|---|
| .NET Framework 4.7.2+ | ✅ |
| .NET Standard 2.0+ | ✅ |
| .NET 8+ | ✅ |
Related Packages
- EnumCraft.Core — Type-safe enumerations and flags
- EnumCraft.Json — JSON serialization extensions for TypedEnum and TypedFlag
- EnumCraft.FeatureFlags.Json — JSON file provider for feature flags
License
MIT — see LICENSE for details.
Author
| 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 is compatible. 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
- EnumCraft.Core (>= 1.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 2.1.1)
-
net8.0
- EnumCraft.Core (>= 1.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 2.1.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on EnumCraft.FeatureFlags:
| Package | Downloads |
|---|---|
|
EnumCraft.FeatureFlags.Json
JSON file provider for EnumCraft.FeatureFlags. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.1 | 155 | 4/26/2026 |
| 1.0.0 | 148 | 4/26/2026 |
| 0.3.1-preview | 142 | 4/22/2026 |
| 0.3.0-preview | 141 | 4/20/2026 |
| 0.2.2-preview | 148 | 4/6/2026 |
| 0.2.1-preview | 154 | 3/2/2026 |
| 0.2.0-preview | 158 | 2/24/2026 |
| 0.1.4-preview | 112 | 2/22/2026 |
| 0.1.3-preview | 116 | 2/19/2026 |
| 0.1.2-preview | 112 | 2/17/2026 |
| 0.1.1-preview | 117 | 2/16/2026 |
| 0.1.0-preview | 118 | 2/16/2026 |