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");
}Microsoft.FeatureManagement |
Swevo.AutoFeatureFlag |
|
|---|---|---|
| Flag access | await featureManager.IsEnabledAsync("DarkMode") |
flags.IsDarkModeEnabled |
| Typos | Runtime crash | Compile error |
| Dependencies | Microsoft.FeatureManagement + Microsoft.Extensions.* |
Zero |
| AOT | ✅ | |
| Test override | Configuration / snapshots | provider.Enable("DarkMode") |
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();
}
}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 Enablepublic 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 ...
}
}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();
}| ID | Severity | Description |
|---|---|---|
AFF001 |
Warning | [FeatureFlags] enum has no members — no code is generated |
| 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 |
| Package | Downloads | Description |
|---|---|---|
| Swevo.AutoBus | Free, MIT-licensed in-process message bus for | |
| Swevo.AutoBus.RabbitMQ | RabbitMQ transport for AutoBus | |
| Swevo.AutoAssert | Free, MIT-licensed fluent assertions for | |
| Swevo.AutoAuth | A free, MIT-licensed fluent configuration wrapper around OpenIddict for building OAuth2/OIDC token servers in ASP | |
| Swevo.AutoAudit | Compile-time audit field generation for EF Core entities using Roslyn source generators | |
| Swevo.AutoResult | Compile-time Result monad for | |
| Swevo.AutoGuard | Compile-time guard clauses for | |
| Swevo.AutoImage | A free, MIT-licensed fluent image processing wrapper around SkiaSharp for | |
| Swevo.AutoTestData | Compile-time test data builders for |
MIT © 2026 Justin Bannister