Skip to content

Swevo/AutoFeatureFlag

Repository files navigation

Swevo.AutoFeatureFlag

NuGet NuGet Downloads CI License: MIT

Compile-time feature flag stubs for .NET. Decorate an enum with [FeatureFlags] and get a strongly-typed interface and class — no reflection, no Microsoft.FeatureManagement overhead, AOT-safe.

[FeatureFlags]
public enum AppFeatures
{
    DarkMode,
    NewCheckout,
    BetaApi
}

// ↓ Generator produces ↓

public interface IAppFeaturesFlags
{
    bool IsDarkModeEnabled   { get; }
    bool IsNewCheckoutEnabled { get; }
    bool IsBetaApiEnabled    { get; }
}

public sealed class AppFeaturesFlags : IAppFeaturesFlags
{
    public AppFeaturesFlags(IFeatureFlagProvider provider) ...
    public bool IsDarkModeEnabled    => provider.IsEnabled("DarkMode");
    public bool IsNewCheckoutEnabled => provider.IsEnabled("NewCheckout");
    public bool IsBetaApiEnabled     => provider.IsEnabled("BetaApi");
}

Why not Microsoft.FeatureManagement?

Microsoft.FeatureManagement Swevo.AutoFeatureFlag
Flag access await featureManager.IsEnabledAsync("DarkMode") flags.IsDarkModeEnabled
Typos Runtime crash Compile error
Dependencies Microsoft.FeatureManagement + Microsoft.Extensions.* Zero
AOT ⚠️ reflection
Test override Configuration / snapshots provider.Enable("DarkMode")

Quick Start

dotnet add package Swevo.AutoFeatureFlag
// 1. Define your flags
[FeatureFlags]
public enum Features { DarkMode, BetaCheckout }

// 2. Wire up (choose your DI framework)
var provider = new InMemoryFeatureFlagProvider();
services.AddSingleton<IFeatureFlagProvider>(provider);
services.AddSingleton<IFeaturesFlags, FeaturesFlags>();

// 3. Inject and use
public class CheckoutService(IFeaturesFlags flags)
{
    public void Process()
    {
        if (flags.IsBetaCheckoutEnabled)
            RunBetaCheckout();
        else
            RunCheckout();
    }
}

InMemoryFeatureFlagProvider

The bundled in-memory provider is thread-safe and defaults all flags to disabled.

var provider = new InMemoryFeatureFlagProvider();

provider.Enable("DarkMode");           // → IsEnabled("DarkMode") == true
provider.Disable("DarkMode");          // → IsEnabled("DarkMode") == false
provider.SetEnabled("DarkMode", true); // same as Enable

Testing

public class CheckoutServiceTests
{
    private readonly InMemoryFeatureFlagProvider _provider = new();
    private readonly FeaturesFlags _flags;

    public CheckoutServiceTests() => _flags = new FeaturesFlags(_provider);

    [Fact]
    public void BetaCheckout_WhenEnabled_UsesBetaPath()
    {
        _provider.Enable("BetaCheckout");
        var sut = new CheckoutService(_flags);
        // assert beta path taken ...
    }
}

Custom Providers

Implement IFeatureFlagProvider to read from any source — configuration, database, LaunchDarkly, etc.:

public sealed class ConfigFeatureFlagProvider(IConfiguration config) : IFeatureFlagProvider
{
    public bool IsEnabled(string flagName)
        => config.GetValue<bool>($"FeatureFlags:{flagName}");

    public void Enable(string flagName)  => throw new NotSupportedException("Use appsettings.json");
    public void Disable(string flagName) => throw new NotSupportedException("Use appsettings.json");
    public void SetEnabled(string flagName, bool enabled) => throw new NotSupportedException();
}

Diagnostics

ID Severity Description
AFF001 Warning [FeatureFlags] enum has no members — no code is generated

Part of the Swevo ecosystem

Package Purpose
Swevo.AutoFeatureFlag This package
Swevo.AutoResult Result<T> + TryWrap wrappers
Swevo.AutoAudit Audit fields (CreatedAt, UpdatedAt)
Swevo.EFCore.SoftDelete Soft delete + global query filters
Swevo.EFCore.StronglyTyped Strongly-typed IDs for EF Core
Swevo.EFCore.Outbox Transactional outbox pattern
AutoLog.Generator Compile-time high-performance LoggerMessage.Define logging
AutoHttpClient.Generator Compile-time typed HTTP client. AOT-safe Refit alternative

Related Packages

Package Downloads Description
Swevo.AutoBus Downloads Free, MIT-licensed in-process message bus for
Swevo.AutoBus.RabbitMQ Downloads RabbitMQ transport for AutoBus
Swevo.AutoAssert Downloads Free, MIT-licensed fluent assertions for
Swevo.AutoAuth Downloads A free, MIT-licensed fluent configuration wrapper around OpenIddict for building OAuth2/OIDC token servers in ASP
Swevo.AutoAudit Downloads Compile-time audit field generation for EF Core entities using Roslyn source generators
Swevo.AutoResult Downloads Compile-time Result monad for
Swevo.AutoGuard Downloads Compile-time guard clauses for
Swevo.AutoImage Downloads A free, MIT-licensed fluent image processing wrapper around SkiaSharp for
Swevo.AutoTestData Downloads Compile-time test data builders for

License

MIT © 2026 Justin Bannister

About

Compile-time feature flag stubs for .NET. [FeatureFlags] on an enum generates a strongly-typed I{Name}Flags interface and class. No strings, no reflection, AOT-safe.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages