Skip to content

Pragmatic.FeatureFlags

Context-aware feature flag evaluation for .NET 10: targeting rules, percentage rollout, and deterministic bucketing.

Apps need runtime control over feature visibility: gradual rollouts, A/B tests, beta programs, kill switches. Plain configuration gives you on/off, but the same value applies to every user, tenant, and environment, so teams hand-roll targeting:

// Without Pragmatic: hand-rolled targeting, duplicated and inconsistent
var isEnabled = betaTenants?.Contains(tenantId) == true
|| ComputeHash(userId) % 100 < rolloutPercent; // different result per hash/seed/rounding

That duplicates the hash-and-check pattern, gives no consistency guarantee (the same user flips between requests), has no change detection (caches serve stale toggles until restart), and conflates static configuration with context-dependent evaluation.

Define flags with targeting rules; a deterministic evaluation engine handles the rest: stable per-user/tenant bucketing (the same input always resolves the same way), percentage rollout, and change watching.

// Define() is on the in-memory store registered by AddPragmaticFeatureFlags()
var store = serviceProvider.GetRequiredService<InMemoryFeatureFlagStore>();
store.Define(new FeatureFlagDefinition
{
Name = "new-checkout",
Enabled = false,
Rules = [ FeatureFlagRule.Percentage(20), FeatureFlagRule.Tenant("beta-co") ] // 20% rollout + beta tenant
});
// Evaluate against an explicit context…
if (await store.IsEnabledAsync("new-checkout", context, ct)) { /* new path */ }
// …or let IFeatureFlags resolve the ambient one through your IFeatureFlagContextProvider:
if (await flags.IsEnabledAsync<NewCheckout>(ct)) { /* new path */ }

IFeatureFlags knows the caller only through an IFeatureFlagContextProvider you register; no package ships one, and multi-tenancy is not bridged automatically. Without it every evaluation uses FeatureFlagContext.Empty: the global state and percentage rules apply, targeting rules never match.

Strongly-typed flags (IFeatureFlag), a configuration-backed store (Pragmatic.FeatureFlags.Configuration) and change notifications are all supported. Changes are broadcast: every watcher sees every change.

Terminal window
dotnet add package Pragmatic.FeatureFlags
dotnet add package Pragmatic.FeatureFlags.Configuration # optional: flags read from IConfiguration

Functional within 1.0.0-alpha: the evaluation engine, targeting rules, deterministic bucketing, strongly-typed flags, and the stores. See the roadmap.

| Concepts | Evaluation engine, rule types, deterministic bucketing, vs configuration | | Getting Started | Define a flag, add targeting, evaluate it | | Stores | Pluggable backends, change watching, strongly-typed flags | | Common Mistakes | The most frequent flag pitfalls | | Troubleshooting | Problem/solution guide |

  • .NET 10.0+

Part of the Pragmatic.Design ecosystem. See Licensing. Pragmatic.FeatureFlags is MIT-licensed.