Propel.FeatureFlags
2.2.1
dotnet add package Propel.FeatureFlags --version 2.2.1
NuGet\Install-Package Propel.FeatureFlags -Version 2.2.1
<PackageReference Include="Propel.FeatureFlags" Version="2.2.1" />
<PackageVersion Include="Propel.FeatureFlags" Version="2.2.1" />
<PackageReference Include="Propel.FeatureFlags" />
paket add Propel.FeatureFlags --version 2.2.1
#r "nuget: Propel.FeatureFlags, 2.2.1"
#:package Propel.FeatureFlags@2.2.1
#addin nuget:?package=Propel.FeatureFlags&version=2.2.1
#tool nuget:?package=Propel.FeatureFlags&version=2.2.1
Propel.FeatureFlags
A flexible, type-safe feature flag library for .NET applications that supports progressive rollouts, A/B testing, and dynamic feature management.
For detailed documentation and examples, visit the repository readme.
Features
- Type-Safe Feature Flags - Define feature flags as strongly-typed classes with compile-time safety
- Multiple Evaluation Modes - Support for simple on/off, scheduled releases, time windows, and targeted rollouts
- Progressive Rollouts - Gradually roll out features to users or tenants based on percentages or targeting rules
- A/B Testing & Variations - Test different implementations with variation support
- Auto-Registration - No deployment step is needed to add new flags: flags are automatically created in the database on first use
- Caching Support - Built-in caching for improved performance
- Multi-Tenant Ready - Evaluate flags based on tenant, user, or custom attributes
Installation
dotnet add package Propel.FeatureFlags
Quick Start
For complete examples including usage in .dotnet legacy frameworks, visit the usage-demo projects.
1. Define a Feature Flag
public class NewProductApiFeatureFlag : FeatureFlagBase
{
public NewProductApiFeatureFlag()
: base(
key: "new-product-api",
name: "New Product API",
description: "Controls Product API versioning (v1 vs v2)",
onOfMode: EvaluationMode.Off)
{
}
}
2. Evaluate the Flag (Application-Scoped)
Simple setup inside of your application code.
//set up optional attributes for targeting rules and variations
var attributes = new Dictionary<string, object>
{
["amount"] = request.Amount,
["currency"] = request.Currency,
["country"] = request.BillingAddress.Country,
["paymentMethod"] = request.PaymentMethod,
["riskScore"] = await CalculateRiskScore(request)
};
// access the flag client via DI if registered in your service collection
IApplicationFlagClient flagClient = serviceProvider.GetRequiredService<IApplicationFlagClient>();
Use IApplicationFlagClient for application-specific flags that auto-register:
// Simple on/off check
var flag = new NewProductApiFeatureFlag();
var isEnabled = await flagClient.IsEnabledAsync(
flag,
tenantId: "tenant-123",
userId: "user-456",
attributes: attributes //optional targeting context
);
if (isEnabled)
{
return GetProductsV2(); // New implementation
}
return GetProductsV1(); // Legacy implementation
3. Use Variations for A/B Testing
// Get specific variation value
var algorithmType = await _flagClient.GetVariationAsync(
flag: new RecommendationAlgorithmFeatureFlag(),
defaultValue: "collaborative-filtering",
userId: userId,
tenantId: "tenant-123",
attributes: attributes // optional targeting context
);
return algorithmType switch
{
"machine-learning" => GetMLRecommendations(userId),
"content-based" => GetContentBasedRecommendations(userId),
_ => GetCollaborativeRecommendations(userId)
};
4. Global Flags (Cross-Application)
Use IGlobalFlagClient for flags shared across multiple applications:
var isEnabled = await _globalFlagClient.IsEnabledAsync(
flagKey: "maintenance-mode",
tenantId: "tenant-123",
... // other parameters as needed
);
5. .NET Dependency Injection Setup
public static IServiceCollection AddFeatureFlagServices(this IServiceCollection services, PropelConfiguration propelConfiguration)
{
services.AddSingleton(propelConfiguration);
services.AddSingleton<IApplicationFlagProcessor, ApplicationFlagProcessor>();
services.AddSingleton<IApplicationFlagClient, ApplicationFlagClient>();
services.AddSingleton<IGlobalFlagProcessor, GlobalFlagProcessor>();
services.AddSingleton<IGlobalFlagClient, GlobalFlagClient>();
// Register evaluation manager with all handlers
services.RegisterEvaluators();
return services;
}
Register evaluators extension method:
internal static IServiceCollection RegisterEvaluators(this IServiceCollection services)
{
// Register evaluation manager with all handlers (can be customized for your use cases)
services.AddSingleton<IEvaluatorsSet>(_ => new EvaluatorsSet(
new HashSet<IEvaluator>(
[ new ActivationScheduleEvaluator(),
new OperationalWindowEvaluator(),
new TargetingRulesEvaluator(),
new TenantRolloutEvaluator(),
new UserRolloutEvaluator(),
])));
return services;
}
Enable auto-registration from your assembly containing feature flag definitions:
internal static IServiceCollection RegisterFlagsFromExecutingAssembly(this IServiceCollection services)
{
var currentAssembly = Assembly.GetEntryAssembly();
var allFlags = currentAssembly
.GetTypes()
.Where(t => typeof(IFeatureFlag).IsAssignableFrom(t)
&& !t.IsInterface
&& !t.IsAbstract);
foreach (var flag in allFlags)
{
var instance = (IFeatureFlag)Activator.CreateInstance(flag)!;
services.AddSingleton(instance);
}
return services;
}
Configure local caching (optional) with LocalCacheConfiguration:
internal static IServiceCollection AddLocalCache(this IServiceCollection services, LocalCacheConfiguration cacheConfiguration)
{
// Add memory cache for local caching layer
services.AddMemoryCache(memOptions =>
{
memOptions.SizeLimit = cacheConfiguration.CacheSizeLimit;
memOptions.CompactionPercentage = 0.25; // Compact 25% when limit reached
});
services.TryAddSingleton(cacheConfiguration);
services.TryAddSingleton<IFeatureFlagCache, LocalFeatureFlagCache>();
return services;
}
Evaluation Modes
- Off/On - Simple disabled/enabled state
- Scheduled - Activate at a specific date/time
- TimeWindow - Active only during specified time ranges
- UserTargeted - Target specific users or rollout percentages
- TenantTargeted - Target specific tenants or rollout percentages
- TargetingRules - Complex rules based on custom attributes
ASP.NET Core Integration
app.MapGet("/products", async (HttpContext context, IFeatureFlagFactory flags) =>
{
var flag = flags.GetFlagByType<NewProductApiFeatureFlag>();
if (await context.IsFeatureFlagEnabledAsync(flag))
{
return Results.Ok(GetProductsV2());
}
return Results.Ok(GetProductsV1());
});
Best Practices
✅ Use feature flags for:
- Technical implementation changes (v1 → v2 APIs)
- Gradual rollouts and canary deployments
- A/B testing different technical approaches
- Time-sensitive feature releases
- Beta features with controlled access
❌ Don't use feature flags for:
- Business logic or user permissions
- Subscription tiers or pricing rules
- Data access control
- Permanent business rules
Architecture
| Layer | Description |
|---|---|
| Flag Client Layer | IApplicationFlagClient / IGlobalFlagClient |
| Flag Processor Layer | Evaluation logic & caching |
| Evaluators Layer | Scheduled, TimeWindow, Targeting, Rollout |
| Repository Layer | IFeatureFlagRepository (your implementation) |
For detailed documentation and examples, visit the GitHub repository.
| 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 was computed. 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
- Knara.UtcStrict (>= 1.1.0)
- Microsoft.Extensions.Caching.Memory (>= 9.0.9)
- System.Text.Json (>= 9.0.9)
- System.Threading.Tasks.Extensions (>= 4.6.3)
NuGet packages (5)
Showing the top 5 NuGet packages that depend on Propel.FeatureFlags:
| Package | Downloads |
|---|---|
|
Propel.FeatureFlags.AspNetCore
ASP.NET Core integration for Propel Feature Flags. Provides middleware for HTTP request processing, context extensions for feature flag evaluation, and user/tenant context extraction from HTTP requests. |
|
|
Propel.FeatureFlags.Attributes
Aspect-Oriented Programming (AOP) integration for Propel Feature Flags using Castle DynamicProxy. Enables declarative feature flag evaluation through the [FeatureFlagged] attribute with support for both synchronous and asynchronous methods, fallback method execution, and automatic proxy generation for runtime interception. |
|
|
Propel.FeatureFlags.PostgreSql
PostgreSQL storage provider for Propel Feature Flags using Npgsql. Handles database operations and schema migraions for feature flag data with automatic schema creation and JSON storage for targeting rules and configurations. |
|
|
Propel.FeatureFlags.Redis
Redis distributed caching provider for Propel Feature Flags using StackExchange.Redis with connection pooling and resilient connection management. Provides distributed caching capabilities for feature flag configurations with configurable TTL and efficient cache clearing for scalable deployments. |
|
|
Propel.FeatureFlags.DependencyInjection.Extensions
Core feature flag models and evaluation engine for .NET applications |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.2.1 | 392 | 10/20/2025 |
| 2.2.1-beta.1.2 | 183 | 10/19/2025 |
| 2.1.1-beta.1.2 | 103 | 10/18/2025 |
| 2.1.0-beta.1.2 | 186 | 10/16/2025 |
| 2.0.0-beta.1.2 | 187 | 10/14/2025 |
| 1.0.1-beta.1 | 218 | 10/7/2025 |
| 1.0.0-beta.1 | 175 | 10/7/2025 |