Strongly-typed feature flags generated from config — no more magic strings.
A Roslyn source generator that reads feature flag definitions from appsettings.json or flags.json at compile time and generates:
- A strongly-typed
IFeatureFlagsinterface withboolproperties - Extension methods for
IFeatureManager - DI registration via
AddFeatureFlags() - String constants for flag names
Microsoft.FeatureManagement uses magic strings:
// Before: runtime errors on typos, invisible to refactoring
if (await featureManager.IsEnabledAsync("DarkMode")) { ... }FeatureFlagGen gives you compile-time safety:
// After: IntelliSense, refactorable, compile-time checked
if (flags.IsDarkModeEnabled) { ... }dotnet add package FeatureFlagGen{
"FeatureManagement": {
"DarkMode": true,
"NewCheckout": false
}
}In your .csproj:
<ItemGroup>
<AdditionalFiles Include="appsettings.json" />
</ItemGroup>builder.Services.AddFeatureManagement();
builder.Services.AddFeatureFlags(); // generated extension methodpublic class MyService
{
private readonly IFeatureFlags _flags;
public MyService(IFeatureFlags flags)
{
_flags = flags;
}
public void DoWork()
{
if (_flags.IsDarkModeEnabled)
{
// dark mode logic
}
}
}Nest flags in JSON to create grouped access:
{
"FeatureManagement": {
"Ui": {
"DarkMode": true,
"SideBar": false
}
}
}Access via nested properties:
if (flags.Ui.IsDarkModeEnabled) { ... }FeatureFlagGen produces five source files:
| File | Contents |
|---|---|
IFeatureFlags.g.cs |
Interface with IsXxxEnabled properties |
FeatureFlags.g.cs |
Implementation wrapping IFeatureManager |
FeatureFlagExtensions.g.cs |
IsXxxEnabledAsync() extension methods on IFeatureManager |
FeatureFlagServiceCollectionExtensions.g.cs |
AddFeatureFlags() DI registration |
FeatureFlagNames.g.cs |
String constants for flag names |
For gradual migration, use the generated extension methods directly on IFeatureManager:
if (await featureManager.IsDarkModeEnabledAsync()) { ... }Access flag name strings via generated constants:
var name = FeatureFlagNames.DarkMode; // "DarkMode"
var grouped = FeatureFlagNames.Ui.DarkMode; // "Ui.DarkMode"Filter-style flag definitions are fully supported:
{
"FeatureManagement": {
"Beta": {
"EnabledFor": [
{ "Name": "Percentage", "Parameters": { "Value": 50 } }
]
}
}
}These are treated as flat flags and generate IsBetaEnabled properties.
The generator recognizes these file names as AdditionalFiles:
appsettings.jsonappsettings.*.json(e.g.,appsettings.Development.json)flags.json
| ID | Severity | Description |
|---|---|---|
| FFG001 | Warning | No FeatureManagement section found in config file |
| FFG002 | Error | Invalid JSON in configuration file |
| FFG003 | Error | Duplicate feature flag name |
- .NET 8.0 or later
Microsoft.FeatureManagementpackage in your application
- Fork the repository
- Create a feature branch (
git checkout -b feat/my-feature) - Write tests for your changes
- Ensure all tests pass:
dotnet test - Ensure formatting:
dotnet format --verify-no-changes - Submit a pull request
MIT — see LICENSE for details.