IFeatureFlagService Extension Methods Reference¶
Overview¶
The FeatureFlagServiceExtensions class provides convenient methods built on top of the core IFeatureFlagService interface. These extension methods simplify common operations and reduce boilerplate code.
Namespace: Flaggy.Extensions
Location: /src/Flaggy/Extensions/FeatureFlagServiceExtensions.cs
Flag State Management Extensions¶
CreateFlagIfNotExistsAsync¶
Creates a flag only if a flag with the same key doesn't already exist.
public static async Task<bool> CreateFlagIfNotExistsAsync(
this IFeatureFlagService service,
string key,
bool isEnabled = false,
string? value = null,
string? description = null,
CancellationToken cancellationToken = default)
Parameters:
- key (string): The unique identifier for the feature flag
- isEnabled (bool, optional): Whether the flag starts enabled (default: false)
- value (string, optional): Optional value associated with the flag
- description (string, optional): Human-readable description
- cancellationToken (CancellationToken, optional): Token to cancel the operation
Returns: Task<bool> - True if created, false if already exists
Example:
// Create flag only if it doesn't exist
bool created = await flagService.CreateFlagIfNotExistsAsync(
key: "dark-mode",
isEnabled: true,
description: "Enable dark mode for user interface"
);
if (created)
{
Console.WriteLine("New flag created");
}
else
{
Console.WriteLine("Flag already exists");
}
Use Cases: - Idempotent initialization of flags - Safe startup configuration - Preventing duplicate flag creation
UpsertFlagAsync¶
Creates or updates a flag (insert/update).
public static async Task<bool> UpsertFlagAsync(
this IFeatureFlagService service,
string key,
bool isEnabled,
string? value = null,
string? description = null,
CancellationToken cancellationToken = default)
Parameters:
- key (string): The unique identifier for the feature flag
- isEnabled (bool): Whether the flag should be enabled
- value (string, optional): Optional value associated with the flag
- description (string, optional): Human-readable description
- cancellationToken (CancellationToken, optional): Token to cancel the operation
Returns: Task<bool> - True if operation succeeded, false otherwise
Example:
// Create or update flag
await flagService.UpsertFlagAsync(
key: "beta-features",
isEnabled: false,
description: "Beta features for testing"
);
// Later, upsert again with updated values
await flagService.UpsertFlagAsync(
key: "beta-features",
isEnabled: true,
value: "phase-2",
description: "Beta features - Phase 2 enabled"
);
Use Cases: - Configuration synchronization - Safe bulk updates - Merge operations from external sources
Flag Toggle Extensions¶
EnableFlagAsync¶
Enables a flag (sets IsEnabled to true).
public static async Task<bool> EnableFlagAsync(
this IFeatureFlagService service,
string key,
CancellationToken cancellationToken = default)
Parameters:
- key (string): The unique identifier for the feature flag
- cancellationToken (CancellationToken, optional): Token to cancel the operation
Returns: Task<bool> - True if successful, false if flag not found
Example:
// Enable a feature
bool enabled = await flagService.EnableFlagAsync("new-checkout-flow");
if (enabled)
{
Console.WriteLine("New checkout flow is now enabled");
}
else
{
Console.WriteLine("Flag not found");
}
Use Cases: - Feature rollout - Activating features - Quick enable operations
DisableFlagAsync¶
Disables a flag (sets IsEnabled to false).
public static async Task<bool> DisableFlagAsync(
this IFeatureFlagService service,
string key,
CancellationToken cancellationToken = default)
Parameters:
- key (string): The unique identifier for the feature flag
- cancellationToken (CancellationToken, optional): Token to cancel the operation
Returns: Task<bool> - True if successful, false if flag not found
Example:
// Disable a feature quickly
bool disabled = await flagService.DisableFlagAsync("beta-features");
if (disabled)
{
Console.WriteLine("Beta features are now disabled");
}
Use Cases: - Emergency feature rollback - Disabling problematic features - Gradual rollout (disable by default)
ToggleFlagAsync¶
Toggles a flag's enabled state (enabled becomes disabled and vice versa).
public static async Task<bool> ToggleFlagAsync(
this IFeatureFlagService service,
string key,
CancellationToken cancellationToken = default)
Parameters:
- key (string): The unique identifier for the feature flag
- cancellationToken (CancellationToken, optional): Token to cancel the operation
Returns: Task<bool> - True if successful, false if flag not found
Example:
// Toggle feature on/off
bool toggled = await flagService.ToggleFlagAsync("maintenance-mode");
var flag = await flagService.GetFlagAsync("maintenance-mode");
Console.WriteLine($"Maintenance mode is now: {(flag?.IsEnabled ? "ON" : "OFF")}");
Use Cases: - Quick feature on/off switching - Admin dashboard toggle buttons - Emergency controls
Flag Update Extensions¶
UpdateFlagValueAsync¶
Updates only the value of a flag, preserving other properties.
public static async Task<bool> UpdateFlagValueAsync(
this IFeatureFlagService service,
string key,
string? value,
CancellationToken cancellationToken = default)
Parameters:
- key (string): The unique identifier for the feature flag
- value (string, optional): The new value
- cancellationToken (CancellationToken, optional): Token to cancel the operation
Returns: Task<bool> - True if successful, false if flag not found
Example:
// Update payment gateway configuration
await flagService.UpdateFlagValueAsync("payment-gateway", "stripe-v3");
// Update feature version
await flagService.UpdateFlagValueAsync("checkout-version", "v2-optimized");
// Clear value
await flagService.UpdateFlagValueAsync("feature-config", null);
Use Cases: - Updating configuration values - Changing provider selections - Version upgrades
UpdateFlagDescriptionAsync¶
Updates only the description of a flag, preserving other properties.
public static async Task<bool> UpdateFlagDescriptionAsync(
this IFeatureFlagService service,
string key,
string? description,
CancellationToken cancellationToken = default)
Parameters:
- key (string): The unique identifier for the feature flag
- description (string, optional): The new description
- cancellationToken (CancellationToken, optional): Token to cancel the operation
Returns: Task<bool> - True if successful, false if flag not found
Example:
// Update description with rollout progress
await flagService.UpdateFlagDescriptionAsync(
"dark-mode",
"Enable dark mode - Rolled out to 25% of users"
);
// Add implementation notes
await flagService.UpdateFlagDescriptionAsync(
"new-api",
"New REST API v3 - Replaces GraphQL layer, active in production"
);
Use Cases: - Documentation updates - Rollout progress tracking - Adding implementation notes
Flag Query Extensions¶
FlagExistsAsync¶
Checks if a flag exists in the system.
public static async Task<bool> FlagExistsAsync(
this IFeatureFlagService service,
string key,
CancellationToken cancellationToken = default)
Parameters:
- key (string): The unique identifier for the feature flag
- cancellationToken (CancellationToken, optional): Token to cancel the operation
Returns: Task<bool> - True if flag exists, false otherwise
Example:
// Check before operations
if (await flagService.FlagExistsAsync("deprecated-feature"))
{
await flagService.DeleteFlagAsync("deprecated-feature");
}
// Validate flag before use
if (!await flagService.FlagExistsAsync("payment-gateway"))
{
throw new InvalidOperationException("Required flag not found");
}
Use Cases: - Precondition checks - Validation before operations - Safe flag deletion
GetEnabledFlagsAsync¶
Retrieves all enabled flags.
public static async Task<IEnumerable<FeatureFlag>> GetEnabledFlagsAsync(
this IFeatureFlagService service,
CancellationToken cancellationToken = default)
Parameters:
- cancellationToken (CancellationToken, optional): Token to cancel the operation
Returns: Task<IEnumerable<FeatureFlag>> - Collection of enabled flags
Example:
// Get all active features
var enabledFlags = await flagService.GetEnabledFlagsAsync();
Console.WriteLine($"Active features ({enabledFlags.Count()}):");
foreach (var flag in enabledFlags)
{
Console.WriteLine($" - {flag.Key}: {flag.Description}");
}
Use Cases: - Admin dashboards - Feature activity reports - Enabled feature inventory
GetDisabledFlagsAsync¶
Retrieves all disabled flags.
public static async Task<IEnumerable<FeatureFlag>> GetDisabledFlagsAsync(
this IFeatureFlagService service,
CancellationToken cancellationToken = default)
Parameters:
- cancellationToken (CancellationToken, optional): Token to cancel the operation
Returns: Task<IEnumerable<FeatureFlag>> - Collection of disabled flags
Example:
// Get all inactive features
var disabledFlags = await flagService.GetDisabledFlagsAsync();
Console.WriteLine($"Inactive features ({disabledFlags.Count()}):");
foreach (var flag in disabledFlags)
{
Console.WriteLine($" - {flag.Key}");
}
// Find flags ready for removal
var oldDisabled = disabledFlags.Where(f =>
DateTime.UtcNow - f.UpdatedAt > TimeSpan.FromDays(90)
);
Use Cases: - Finding deprecated features - Cleanup operations - Feature inventory management
Bulk Operation Extensions¶
DeleteFlagsAsync¶
Deletes multiple flags by their keys.
public static async Task<int> DeleteFlagsAsync(
this IFeatureFlagService service,
IEnumerable<string> keys,
CancellationToken cancellationToken = default)
Parameters:
- keys (IEnumerablecancellationToken (CancellationToken, optional): Token to cancel the operation
Returns: Task<int> - Number of flags successfully deleted
Example:
// Delete multiple flags
var keysToDelete = new[] { "old-feature", "deprecated-api", "temp-flag" };
int deletedCount = await flagService.DeleteFlagsAsync(keysToDelete);
Console.WriteLine($"Deleted {deletedCount} flags");
// Delete flags matching a condition
var disabledOldFlags = (await flagService.GetDisabledFlagsAsync())
.Where(f => DateTime.UtcNow - f.UpdatedAt > TimeSpan.FromDays(30))
.Select(f => f.Key);
await flagService.DeleteFlagsAsync(disabledOldFlags);
Use Cases: - Batch deletion - Migration cleanups - Archive management
DeleteAllDisabledFlagsAsync¶
Deletes all disabled flags in the system.
public static async Task<int> DeleteAllDisabledFlagsAsync(
this IFeatureFlagService service,
CancellationToken cancellationToken = default)
Parameters:
- cancellationToken (CancellationToken, optional): Token to cancel the operation
Returns: Task<int> - Number of disabled flags deleted
Example:
// Clean up all disabled flags
int deletedCount = await flagService.DeleteAllDisabledFlagsAsync();
Console.WriteLine($"Cleaned up {deletedCount} disabled flags");
Use Cases: - System maintenance - Archive cleanup - Removing deprecated features
Initialization Extensions¶
SeedFlagsAsync¶
Creates initial flags only if they don't already exist (idempotent seeding).
public static async Task SeedFlagsAsync(
this IFeatureFlagService service,
IEnumerable<FeatureFlag> flags,
CancellationToken cancellationToken = default)
Parameters:
- flags (IEnumerablecancellationToken (CancellationToken, optional): Token to cancel the operation
Example:
// Seed default flags at startup
await flagService.SeedFlagsAsync(new[]
{
new FeatureFlag
{
Key = "dark-mode",
IsEnabled = false,
Description = "Enable dark mode"
},
new FeatureFlag
{
Key = "beta-dashboard",
IsEnabled = false,
Description = "New dashboard design"
},
new FeatureFlag
{
Key = "maintenance-mode",
IsEnabled = false,
Description = "Enable maintenance mode"
}
});
Use Cases: - Application startup initialization - Database population scripts - Configuration as code - Idempotent deployments
Reporting Extensions¶
GetFlagsSummaryAsync¶
Retrieves summary statistics about all flags.
public static async Task<FlagsSummary> GetFlagsSummaryAsync(
this IFeatureFlagService service,
CancellationToken cancellationToken = default)
Returns: Task<FlagsSummary> - Summary object with statistics
FlagsSummary Structure:
public class FlagsSummary
{
public int TotalCount { get; set; } // Total number of flags
public int EnabledCount { get; set; } // Number of enabled flags
public int DisabledCount { get; set; } // Number of disabled flags
}
Example:
// Get summary statistics
var summary = await flagService.GetFlagsSummaryAsync();
Console.WriteLine($"Feature Flags Summary:");
Console.WriteLine($" Total: {summary.TotalCount}");
Console.WriteLine($" Enabled: {summary.EnabledCount}");
Console.WriteLine($" Disabled: {summary.DisabledCount}");
// Check enable rate
var enableRate = (double)summary.EnabledCount / summary.TotalCount * 100;
Console.WriteLine($" Enable Rate: {enableRate:F1}%");
Use Cases: - Admin dashboards - System monitoring - Feature inventory reports - Health checks
Common Usage Patterns¶
Pattern 1: Feature Initialization¶
public class Startup
{
public async Task InitializeAsync(IFeatureFlagService flagService)
{
// Create flags only if they don't exist
await flagService.SeedFlagsAsync(new[]
{
new FeatureFlag { Key = "feature-a", IsEnabled = true },
new FeatureFlag { Key = "feature-b", IsEnabled = false },
});
}
}
Pattern 2: Feature Toggling in Controllers¶
[ApiController]
public class FeatureController : ControllerBase
{
private readonly IFeatureFlagService _flagService;
[HttpPost("toggle/{key}")]
public async Task<IActionResult> Toggle(string key)
{
bool toggled = await _flagService.ToggleFlagAsync(key);
return toggled ? Ok("Toggled") : NotFound();
}
[HttpPost("enable/{key}")]
public async Task<IActionResult> Enable(string key)
{
bool enabled = await _flagService.EnableFlagAsync(key);
return enabled ? Ok("Enabled") : NotFound();
}
}
Pattern 3: Admin Dashboard¶
public class DashboardController : ControllerBase
{
private readonly IFeatureFlagService _flagService;
[HttpGet("stats")]
public async Task<IActionResult> GetStats()
{
var summary = await _flagService.GetFlagsSummaryAsync();
var enabled = await _flagService.GetEnabledFlagsAsync();
return Ok(new {
summary,
enabledFeatures = enabled.Select(f => f.Key)
});
}
}
Pattern 4: Cleanup Task¶
public class MaintenanceService
{
private readonly IFeatureFlagService _flagService;
public async Task CleanupDeprecatedFlagsAsync()
{
var deletedCount = await _flagService.DeleteAllDisabledFlagsAsync();
Console.WriteLine($"Cleaned up {deletedCount} deprecated flags");
}
}
Related Documentation¶
- Core Service: IFeatureFlagService Interface
- Provider: IFeatureFlagProvider Interface
- Models: FeatureFlag Model