### Basic Targeting Filter Setup Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/TargetingFilter.md Demonstrates a basic setup for the TargetingFilter in a feature management configuration, including targeting specific users and groups with rollout percentages. ```APIDOC ### Basic Targeting Filter Setup ```json { "FeatureManagement": { "BetaFeature": { "EnabledFor": [ { "Name": "Microsoft.Targeting", "Parameters": { "Audience": { "Users": ["user1@example.com", "user2@example.com"], "Groups": [ { "Name": "beta-testers", "RolloutPercentage": 100 }, { "Name": "power-users", "RolloutPercentage": 50 } ] } } } ] } } } ``` ### Configuration Properties **Audience Object:** - `Users`: Array of specific user IDs/emails to include - `Groups`: Array of group definitions **Group Object:** - `Name`: Group identifier (required) - `RolloutPercentage`: Percentage of group members to include (0-100, default 100) ``` -------------------------------- ### Staged Rollout Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/TargetingFilter.md Example configuration demonstrating a staged rollout for a feature ('MajorUpdate') by targeting both specific users and groups with different rollout percentages. ```APIDOC ### Staged Rollout ```json { "FeatureManagement": { "MajorUpdate": { "EnabledFor": [ { "Name": "Microsoft.Targeting", "Parameters": { "Audience": { "Users": ["qa-team@company.com"], "Groups": [ { "Name": "internal", "RolloutPercentage": 100 }, { "Name": "customers", "RolloutPercentage": 10 } ] } } } ] } } } ``` ``` -------------------------------- ### PercentageFilter Configuration Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureFilter.md Example JSON configuration for enabling a feature for a specific percentage of users using the built-in PercentageFilter. ```json { "MyFeature": { "EnabledFor": [ { "Name": "Microsoft.Percentage", "Parameters": { "Value": 50 } } ] } } ``` -------------------------------- ### Direct User Targeting Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/TargetingFilter.md Example configuration for enabling a feature ('AdminPanel') only for specific direct user IDs. ```APIDOC ### Direct User Targeting ```json { "FeatureManagement": { "AdminPanel": { "EnabledFor": [ { "Name": "Microsoft.Targeting", "Parameters": { "Audience": { "Users": ["admin@company.com", "manager@company.com"] } } } ] } } } ``` ``` -------------------------------- ### Complete Feature Management Registration Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/ServiceCollectionExtensions.md A comprehensive example showing the registration of feature management, including configuration loading, adding multiple built-in filters, enabling targeting, and configuring a disabled features handler. ```csharp public void ConfigureServices(IServiceCollection services) { // Add configuration var configuration = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .Build(); // Register feature management services.AddFeatureManagement(configuration) // Add built-in filters .AddFeatureFilter() .AddFeatureFilter() .AddFeatureFilter() // Enable targeting context .WithTargeting() // Configure disabled feature handler .UseDisabledFeaturesHandler(new NotFoundDisabledFeaturesHandler()); // Add other services services.AddControllers(); services.AddRazorPages(); } ``` -------------------------------- ### Register Feature Management with Filters and Targeting Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/ServiceCollectionExtensions.md Example of adding feature management to services, registering specific feature filters, and enabling targeting context. This is a common setup for dynamic feature control. ```csharp var builder = WebApplication.CreateBuilder(args); var config = builder.Configuration; builder.Services.AddFeatureManagement(config) .AddFeatureFilter() .WithTargeting(); var app = builder.Build(); ``` -------------------------------- ### Group-Based Targeting Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/TargetingFilter.md Example configuration for enabling a feature ('NewUI') for members of a specific group with a defined rollout percentage. ```APIDOC ### Group-Based Targeting ```json { "FeatureManagement": { "NewUI": { "EnabledFor": [ { "Name": "Microsoft.Targeting", "Parameters": { "Audience": { "Groups": [ { "Name": "early-adopters", "RolloutPercentage": 100 } ] } } } ] } } } ``` ``` -------------------------------- ### Complete ASP.NET Core Feature Management Setup Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/AspNetCoreFeatureManagementBuilderExtensions.md Demonstrates a complete setup for feature management in an ASP.NET Core application. This includes registering feature management, adding various feature filters, enabling targeting, and configuring a custom handler for disabled features using a redirect. ```csharp var builder = WebApplication.CreateBuilder(args); // Register feature management builder.Services.AddFeatureManagement(builder.Configuration) // Add filters .AddFeatureFilter() .AddFeatureFilter() .AddFeatureFilter() // Enable targeting based on HTTP context .WithTargeting() // Custom handler for disabled features .UseDisabledFeaturesHandler((features, context) => { context.Result = new RedirectToPageResult("/FeatureDisabled", new { returnUrl = context.HttpContext.Request.Path }); return Task.CompletedTask; }); builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers(); app.Run(); ``` -------------------------------- ### TargetingFilter Configuration Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureFilter.md Example JSON configuration for enabling a feature for targeted users and groups using the built-in TargetingFilter. Allows specifying users, groups, and rollout percentages. ```json { "BetaFeature": { "EnabledFor": [ { "Name": "Microsoft.Targeting", "Parameters": { "Audience": { "Users": ["user@example.com"], "Groups": [ { "Name": "beta-testers", "RolloutPercentage": 100 } ] } } } ] } } ``` -------------------------------- ### TimeWindowFilter Configuration Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureFilter.md Example JSON configuration for enabling a feature during a specific time window using the built-in TimeWindowFilter. Supports optional recurrence. ```json { "MaintenanceMode": { "EnabledFor": [ { "Name": "Microsoft.TimeWindow", "Parameters": { "Start": "2024-06-16T22:00:00Z", "End": "2024-06-17T02:00:00Z", "Recurrence": { "Pattern": "Daily", "Interval": 1 } } } ] } } ``` -------------------------------- ### Install Feature Management NuGet Packages Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/README.md Installs the core feature management library and the ASP.NET Core integration package. ```bash dotnet add package Microsoft.FeatureManagement dotnet add package Microsoft.FeatureManagement.AspNetCore ``` -------------------------------- ### Invalid Configuration - Time Window Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/errors.md Shows an invalid date format for the 'Start' parameter in a TimeWindow filter configuration, leading to an InvalidConfigurationSetting error. ```json { "EnabledFor": [ { "Name": "Microsoft.TimeWindow", "Parameters": { "Start": "invalid-date" } } ] } ``` -------------------------------- ### Targeting Filter Configuration Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/AspNetCoreFeatureManagementBuilderExtensions.md Illustrates the JSON configuration for the Targeting Filter. This example enables 'BetaFeature' for users in the 'beta-testers' group with a 100% rollout percentage. It also notes that targeting context is automatically extracted from HttpContext claims. ```json { "FeatureManagement": { "BetaFeature": { "EnabledFor": [ { "Name": "Microsoft.Targeting", "Parameters": { "Audience": { "Groups": [ { "Name": "beta-testers", "RolloutPercentage": 100 } ] } } } ] } } } // Targeting context automatically extracted from HttpContext claims // User groups from claims with type "group" // User ID from claim type "sub" or "nameid" ``` -------------------------------- ### A/B Testing Setup Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/SUMMARY.txt Configure and implement A/B tests using feature variants. This involves defining variants and their associated allocation rules. ```csharp // Configuration example (appsettings.json): // "MyABTestFeature": { // "Variants": [ // { "name": "Control", "weight": 50 }, // { "name": "VariantA", "weight": 50, "configuration": { "ui_color": "blue" } } // ] // } ``` -------------------------------- ### FeatureTagHelper Name Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureTagHelper.md Example of using the 'name' attribute to conditionally render content when the 'NewUI' feature is enabled. ```html ``` -------------------------------- ### FeatureTagHelper Negate Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureTagHelper.md Example of using the 'negate' attribute to display legacy UI content only when the 'NewUI' feature is disabled. ```html
Legacy interface
``` -------------------------------- ### Multiple Variants Rendering Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureTagHelper.md Example of rendering experimental pricing page content if the user is assigned to any of the specified variants ('control', 'treatment-1', 'treatment-2') for the 'Pricing' feature. ```html

Experimental pricing page

``` -------------------------------- ### Custom Configuration Sources Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/SUMMARY.txt Integrate custom configuration sources to manage feature flags dynamically. This example shows how to add a custom provider. ```csharp builder.Host.ConfigureAppConfiguration(config => { config.Add(new DatabaseConfigurationSource()); // Assuming DatabaseConfigurationSource is defined }); ``` -------------------------------- ### Configuration Feature Management JSON Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureDefinitionProvider.md Example JSON structure for configuring features using ConfigurationFeatureDefinitionProvider. Features can be defined in the 'FeatureManagement' section or at the root level. ```json { "FeatureManagement": { "MyFeature": { "Enabled": true, "EnabledFor": [] } } } ``` -------------------------------- ### Custom Configuration Provider (Database Example) Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/SUMMARY.txt Create a custom configuration provider to load feature flag settings from a database. This allows for dynamic management of features without redeploying the application. ```csharp public class DatabaseConfigurationProvider : ConfigurationProvider { public override void Load() { // Load configuration from database // Example: Data = LoadFromDatabase(); } } ``` -------------------------------- ### FeatureTagHelper Variant Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureTagHelper.md Example of rendering content when a user is assigned to 'variant-a' or 'variant-b' for the 'ExperimentalUI' feature. The 'Requirement' property is ignored when 'Variant' is used. ```html
User in experiment group
``` -------------------------------- ### Composite Feature Definition Provider Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureDefinitionProvider.md Demonstrates how to create a composite provider that aggregates definitions from multiple sources. This is useful for fallback scenarios. ```csharp public class CompositeFeatureDefinitionProvider : IFeatureDefinitionProvider { private readonly IEnumerable _providers; private readonly ILogger _logger; public CompositeFeatureDefinitionProvider( IEnumerable providers, ILogger logger) { _providers = providers; _logger = logger; } public async Task GetFeatureDefinitionAsync(string featureName) { foreach (var provider in _providers) { try { var definition = await provider.GetFeatureDefinitionAsync(featureName); if (definition != null) { return definition; } } catch (Exception ex) { _logger.LogWarning(ex, $"Provider failed for {featureName}"); continue; } } return null; } public async IAsyncEnumerable GetAllFeatureDefinitionsAsync() { var seen = new HashSet(); foreach (var provider in _providers) { try { await foreach (var def in provider.GetAllFeatureDefinitionsAsync()) { if (seen.Add(def.Name)) { yield return def; } } } catch (Exception ex) { _logger.LogWarning(ex, "Provider failed to get all definitions"); continue; } } } } // Register services.AddSingleton(sp => new CompositeFeatureDefinitionProvider( new IFeatureDefinitionProvider[] { new ConfigurationFeatureDefinitionProvider(configuration), new DatabaseFeatureDefinitionProvider(connectionFactory, logger) }, logger )); ``` -------------------------------- ### Simple Feature Check Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureTagHelper.md Basic usage of the FeatureTagHelper to conditionally render content when the 'NewDashboard' feature is enabled. ```html
``` -------------------------------- ### Feature Manager Integration Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureDefinitionProvider.md Shows how to integrate an IFeatureDefinitionProvider with the FeatureManager, both directly and via dependency injection. ```csharp var provider = new ConfigurationFeatureDefinitionProvider(configuration); var featureManager = new FeatureManager(provider); // Or via dependency injection services.AddFeatureManagement(configuration); // ConfigurationFeatureDefinitionProvider is automatically registered ``` -------------------------------- ### Multiple Features Rendering Examples Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureTagHelper.md Demonstrates conditional rendering for multiple features using 'All' (both must be enabled) and 'Any' (at least one must be enabled) requirements. ```html
Premium Analytics View
Advanced features available
``` -------------------------------- ### Using Custom Filter in Configuration Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureFilter.md Example JSON configuration demonstrating how to use a custom feature filter by its registered alias and providing parameters. ```json { "MyFeature": { "EnabledFor": [ { "Name": "MyCompany.CustomFilter", "Parameters": { "CustomValue": "enabled" } } ] } } ``` -------------------------------- ### Variant-Based Rendering Examples Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureTagHelper.md Shows how to render different UI variations ('control', 'variant-a', 'variant-b') for the 'Checkout' feature based on assigned user variants. ```html

Standard checkout experience

Simplified one-page checkout

Modal-based checkout wizard

``` -------------------------------- ### FeatureTagHelper Requirement Examples Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureTagHelper.md Demonstrates using the 'requirement' attribute to enforce that all specified features must be enabled ('All') or that at least one must be enabled ('Any'). ```html Both features enabled At least one theme feature enabled ``` -------------------------------- ### Negation (Fallback UI) Examples Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureTagHelper.md Illustrates using the 'negate' attribute to show fallback UI when a feature is disabled, and the standard UI when it's enabled. ```html ``` -------------------------------- ### Invalid Configuration - Percentage Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/errors.md Demonstrates an invalid percentage value (150) in the FeatureManagement configuration, which would trigger an InvalidConfigurationSetting error. ```json { "FeatureManagement": { "MyFeature": { "EnabledFor": [ { "Name": "Microsoft.Percentage", "Parameters": { "Value": 150 } } ] } } } ``` -------------------------------- ### IFilterParametersBinder Implementation Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureFilter.md Example of implementing IFeatureFilter along with IFilterParametersBinder to parse complex configuration parameters into a strongly-typed settings object. ```csharp public class AdvancedFilter : IFeatureFilter, IFilterParametersBinder { public object BindParameters(IConfiguration filterParameters) { // Parse configuration into strongly-typed settings return filterParameters.Get(); } public Task EvaluateAsync(FeatureFilterEvaluationContext context) { var settings = (AdvancedFilterSettings)context.Settings; return Task.FromResult(EvaluateSettings(settings)); } } ``` -------------------------------- ### JSON Configuration for EnabledFor Array with Targeting Filter Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/configuration.md Illustrates the structure of the 'EnabledFor' array within a feature configuration, specifically using the 'Microsoft.Targeting' filter. This example enables the feature for a specific user and a group of beta testers. ```json { "EnabledFor": [ { "Name": "Microsoft.Targeting", "Parameters": { "Audience": { "Users": ["user@example.com"], "Groups": [ { "Name": "beta-testers", "RolloutPercentage": 100 } ] } } } ] } ``` -------------------------------- ### Get All Feature Definitions Async Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureDefinitionProvider.md Retrieves all registered feature definitions asynchronously. Useful for iterating through all available features. ```csharp IAsyncEnumerable GetAllFeatureDefinitionsAsync() ``` ```csharp var provider = serviceProvider.GetRequiredService(); await foreach (var definition in provider.GetAllFeatureDefinitionsAsync()) { Console.WriteLine($"Feature: {definition.Name}"); } ``` -------------------------------- ### Configuration for Missing Feature Filter Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/errors.md Example JSON configuration demonstrating a missing feature filter. This can be resolved by registering the filter or by configuring the system to ignore missing filters. ```json { "FeatureManagement": { "MyFeature": { "EnabledFor": [ { "Name": "MissingFilter" } ] } } } ``` -------------------------------- ### Multi-Source Composition Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/SUMMARY.txt Compose feature flags from multiple configuration sources. This allows for a flexible and robust feature management setup. ```csharp // The configuration system in .NET Core supports multiple sources by default. // Ensure your custom sources are added in the desired order. ``` -------------------------------- ### Complete Feature Management JSON Configuration Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/configuration.md This JSON configuration defines various features with their enablement status, targeting rules, variants, and allocation settings. It includes examples for conditional rollout, time-based windows, and percentage-based rollouts. ```json { "FeatureManagement": { "NewUI": { "Enabled": false, "RequirementType": "Any", "Status": "Conditional", "EnabledFor": [ { "Name": "Microsoft.Targeting", "Parameters": { "Audience": { "Users": ["early-adopter@company.com"], "Groups": [ { "Name": "beta-testers", "RolloutPercentage": 100 }, { "Name": "internal", "RolloutPercentage": 50 } ] } } } ], "Variants": [ { "Name": "control", "ConfigurationValue": { "Version": "v1", "Layout": "classic", "Colors": "standard" } }, { "Name": "modern", "ConfigurationValue": { "Version": "v2", "Layout": "card-based", "Colors": "modern-palette" } } ], "Allocation": { "DefaultWhenEnabled": "control", "Percentile": [ { "Variant": "control", "From": 0, "To": 60 }, { "Variant": "modern", "From": 60, "To": 100 } ], "Seed": "NewUIExperiment" }, "Telemetry": { "Enabled": true } }, "MaintenanceMode": { "Enabled": false, "EnabledFor": [ { "Name": "Microsoft.TimeWindow", "Parameters": { "Start": "2024-06-16T22:00:00Z", "End": "2024-06-16T23:00:00Z", "Recurrence": { "Pattern": "Weekly", "Interval": 1, "Range": { "Type": "EndDate", "EndDate": "2024-12-31T23:59:59Z" } } } } ] }, "LimitedRollout": { "Enabled": false, "EnabledFor": [ { "Name": "Microsoft.Percentage", "Parameters": { "Value": 10 } } ] } } } ``` -------------------------------- ### Configure FeatureManagementOptions for Missing Features/Filters Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/configuration.md This example configures FeatureManagementOptions to throw exceptions when a feature is not defined or a feature filter is not registered. Use this to enforce feature definition completeness. ```csharp services.Configure(options => { // Throw exception if feature is not defined options.IgnoreMissingFeatures = false; // Throw exception if feature filter is not registered options.IgnoreMissingFeatureFilters = false; }); ``` -------------------------------- ### Implement Custom Targeting Context Accessor Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/AspNetCoreFeatureManagementBuilderExtensions.md Demonstrates how to implement a custom ITargetingContextAccessor to extract targeting information from custom sources, such as HTTP headers. This example shows extracting user ID and groups from 'X-User-Id' and 'X-User-Groups' headers. ```csharp public class CustomTargetingContextAccessor : ITargetingContextAccessor { private readonly IHttpContextAccessor _httpContextAccessor; public CustomTargetingContextAccessor(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public async Task GetContextAsync() { var httpContext = _httpContextAccessor.HttpContext; // Extract user ID and groups from custom source var userId = httpContext?.Request.Headers["X-User-Id"].ToString(); var groups = httpContext?.Request.Headers["X-User-Groups"] .ToString() .Split(',') .Select(g => g.Trim()); return new TargetingContext { UserId = userId, Groups = groups ?? Enumerable.Empty() }; } } // Register services.AddFeatureManagement(configuration) .WithTargeting(); services.AddScoped(); ``` -------------------------------- ### Checking Feature State Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/errors.md Example of checking a feature's state, which may throw an InvalidConfigurationSetting error if the configuration is malformed (e.g., percentage > 100). ```csharp var result = await featureManager.IsEnabledAsync("MyFeature"); // May throw InvalidConfigurationSetting error for percentage > 100 ``` -------------------------------- ### Usage in Controllers Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureManagerSnapshot.md Example demonstrating how to inject and use IFeatureManagerSnapshot within an ASP.NET Core controller to check feature enablement and retrieve feature variants. ```APIDOC ## Usage in Controllers ```csharp [ApiController] [Route("api/[controller]")] public class FeaturesController : ControllerBase { private readonly IFeatureManagerSnapshot _featureManager; public FeaturesController(IFeatureManagerSnapshot featureManager) { _featureManager = featureManager; } [HttpGet("{name}")] public async Task> CheckFeature(string name) { var enabled = await _featureManager.IsEnabledAsync(name); return Ok(enabled); } [HttpGet("{name}/variant")] public async Task> GetVariant(string name) { var variant = await _featureManager.GetVariantAsync(name); return Ok(variant?.Name); } } ``` ``` -------------------------------- ### Custom ITargetingContextAccessor Implementation Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/TargetingFilter.md Provides a custom implementation of ITargetingContextAccessor to extract targeting information from HTTP context, such as user ID and custom claims. This example shows how to register the custom accessor. ```csharp public class CustomTargetingContextAccessor : ITargetingContextAccessor { private readonly IHttpContextAccessor _httpContextAccessor; public CustomTargetingContextAccessor(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public async Task GetContextAsync() { var httpContext = _httpContextAccessor.HttpContext; // Extract from request var userId = httpContext?.User?.FindFirst("sub")?.Value; var groups = httpContext?.User?.FindAll("organization")?.Select(c => c.Value); return new TargetingContext { UserId = userId, Groups = groups ?? Enumerable.Empty() }; } } // Register custom accessor services.AddFeatureManagement(configuration) .AddFeatureFilter() .WithTargeting(); services.AddScoped(); ``` -------------------------------- ### Ambiguous Feature Filter Registration Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/errors.md Illustrates how registering multiple feature filters with the same alias can lead to an AmbiguousFeatureFilter exception. Use distinct aliases for each filter. ```csharp // This creates ambiguity - two filters with same alias [FilterAlias("CustomFilter")] public class FilterV1 : IFeatureFilter { } [FilterAlias("CustomFilter")] public class FilterV2 : IFeatureFilter { } services.AddFeatureManagement() .AddFeatureFilter() .AddFeatureFilter(); // Ambiguous! // Resolution: // Use different aliases [FilterAlias("CustomFilter.V1")] public class FilterV1 : IFeatureFilter { } [FilterAlias("CustomFilter.V2")] public class FilterV2 : IFeatureFilter { } ``` -------------------------------- ### Resilient Feature Definition Provider Example Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureDefinitionProvider.md Implements a resilient provider that falls back to the last known definition in case of errors during retrieval. ```csharp public class ResilientFeatureDefinitionProvider : IFeatureDefinitionProvider { private readonly IFeatureDefinitionProvider _innerProvider; private readonly ILogger _logger; private FeatureDefinition _lastKnownDefinition; public async Task GetFeatureDefinitionAsync(string featureName) { try { var definition = await _innerProvider.GetFeatureDefinitionAsync(featureName); if (definition != null) { _lastKnownDefinition = definition; } return definition; } catch (Exception ex) { _logger.LogError(ex, "Failed to retrieve feature definition"); // Fall back to last known state return _lastKnownDefinition; } } public IAsyncEnumerable GetAllFeatureDefinitionsAsync() { return _innerProvider.GetAllFeatureDefinitionsAsync(); } } ``` -------------------------------- ### Custom Filter Implementation Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/SUMMARY.txt Implement custom feature filters to extend the library's capabilities. This example shows a basic structure for a custom filter that can be used to gate features based on specific criteria. ```csharp public class MyCustomFilter : IFeatureFilter { public Task EvaluateAsync(FeatureFilterEvaluationContext context) { // Custom evaluation logic here return Task.FromResult(true); } } ``` -------------------------------- ### Running the ParametersObject Console App Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/examples/ParametersObjectConsoleApp/README.md Command to run the console application. Ensure you are in the project directory. ```bash dotnet run --project examples/ParametersObjectConsoleApp/ParametersObjectConsoleApp.csproj ``` -------------------------------- ### AssignerOptions Property Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureManager.md Gets or sets the options controlling how variants are assigned during feature evaluation. ```APIDOC ## Properties AssignerOptions ### Description Options controlling how variants are assigned during feature evaluation. ### Type `TargetingEvaluationOptions` ``` -------------------------------- ### TargetingContextAccessor Property Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureManager.md Gets or sets the accessor for retrieving the current targeting context in the application. ```APIDOC ## Properties TargetingContextAccessor ### Description Accessor for retrieving the current targeting context in the application. ### Type `ITargetingContextAccessor` or null ``` -------------------------------- ### Logger Property Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureManager.md Gets or sets the logger for diagnostic and warning messages during feature evaluation. ```APIDOC ## Properties Logger ### Description Logger for diagnostic and warning messages during feature evaluation. ### Type `ILogger` (from `Microsoft.Extensions.Logging`) ``` -------------------------------- ### FeatureFilters Property Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureManager.md Gets or sets the collection of feature filter metadata used during evaluation. ```APIDOC ## Properties FeatureFilters ### Description The collection of feature filter metadata that can be used during evaluation. ### Type `IEnumerable` **Throws:** `ArgumentNullException` if set to null. ### Example ```csharp var filters = new IFeatureFilterMetadata[] { new PercentageFilter(), new TimeWindowFilter(), new TargetingFilter(contextAccessor) }; featureManager.FeatureFilters = filters; ``` ``` -------------------------------- ### A/B Testing with FeatureTagHelper Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureTagHelper.md Demonstrates how to use the FeatureTagHelper for A/B testing by rendering different content based on the 'CheckoutV2' feature flag. The `negate="true"` attribute on the first feature ensures the control version is shown when 'CheckoutV2' is disabled. ```html
@Html.PartialAsync("_CheckoutV1")
@Html.PartialAsync("_CheckoutV2")
``` -------------------------------- ### A/B Testing Configuration Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/README.md Configures an A/B test for 'CheckoutExperiment' with variants, allocation percentages, and targeting for beta testers. ```json { "FeatureManagement": { "CheckoutExperiment": { "Enabled": false, "EnabledFor": [ { "Name": "Microsoft.Targeting", "Parameters": { "Audience": { "Groups": [ { "Name": "beta-testers", "RolloutPercentage": 100 } ] } } } ], "Variants": [ { "Name": "control", "ConfigurationValue": { "Version": "v1" } }, { "Name": "treatment", "ConfigurationValue": { "Version": "v2" } } ], "Allocation": { "DefaultWhenEnabled": "control", "Percentile": [ { "Variant": "control", "From": 0, "To": 50 }, { "Variant": "treatment", "From": 50, "To": 100 } ] } } } } ``` -------------------------------- ### Cache Property Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureManager.md Gets or sets the memory cache for storing computed filter settings and recurrence evaluations. ```APIDOC ## Properties Cache ### Description Memory cache for storing computed filter settings and recurrence evaluations. ### Type `IMemoryCache` (from `Microsoft.Extensions.Caching.Memory`) ``` -------------------------------- ### SessionManagers Property Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureManager.md Gets or sets the collection of session managers used for session-based feature state overrides. ```APIDOC ## Properties SessionManagers ### Description The collection of session managers used for session-based feature state overrides. ### Type `IEnumerable` **Throws:** `ArgumentNullException` if set to null. ``` -------------------------------- ### TimeWindowFilterSettings Class Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/types.md Defines settings for time window-based feature filtering, including start, end, and recurrence. ```csharp namespace Microsoft.FeatureManagement.FeatureFilters; public class TimeWindowFilterSettings { public DateTimeOffset? Start { get; set; } public DateTimeOffset? End { get; set; } public Recurrence Recurrence { get; set; } } ``` -------------------------------- ### Override Configuration via Environment Variables Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/configuration.md Demonstrates how to override simple and nested feature management configurations using environment variables with colon-separated paths. ```bash # Override a simple feature export FeatureManagement__MyFeature__Enabled=true # Override nested configuration export FeatureManagement__TargetedFeature__EnabledFor__0__Name=Microsoft.Percentage export FeatureManagement__TargetedFeature__EnabledFor__0__Parameters__Value=75 ``` -------------------------------- ### FeatureGateAttribute Constructor (All Options) Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureGateAttribute.md Use this constructor to specify all configuration options: requirement type, negation, and features. This provides the most flexibility for complex gating scenarios. ```csharp public FeatureGateAttribute(RequirementType requirementType, bool negate, params string[] features) ``` ```csharp [FeatureGate(RequirementType.Any, true, "OldFeature1", "OldFeature2")] public IActionResult Deprecated() { return View(); } ``` -------------------------------- ### Get Feature Definition Async Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureDefinitionProvider.md Retrieves the definition of a specific feature by its name. Returns null if the feature is not found. ```csharp Task GetFeatureDefinitionAsync(string featureName) ``` ```csharp var provider = serviceProvider.GetRequiredService(); var definition = await provider.GetFeatureDefinitionAsync("MyFeature"); if (definition != null) { Console.WriteLine($"Feature: {definition.Name}"); Console.WriteLine($"Status: {definition.Status}"); Console.WriteLine($"Filters: {definition.EnabledFor.Count()}"); } ``` -------------------------------- ### Singleton vs. Scoped Provider Registration Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureDefinitionProvider.md Illustrates registering IFeatureDefinitionProvider as a singleton for static configuration or as scoped for per-request variations. ```csharp // Singleton (default) - appropriate for static configuration services.AddSingleton( new ConfigurationFeatureDefinitionProvider(configuration)); // Scoped - appropriate if definitions vary per-request services.AddScoped(sp => new ScopedFeatureDefinitionProvider(sp.GetRequiredService())); ``` -------------------------------- ### Registering a Custom Feature Filter Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureFilter.md Example of registering a custom feature filter in the dependency injection container using AddFeatureFilter. ```csharp builder.Services.AddFeatureManagement() .AddFeatureFilter(); ``` -------------------------------- ### Get Feature Names Async Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IVariantFeatureManager.md Retrieves an asynchronous enumeration of all registered feature names. Use this to iterate through all available features. ```csharp var variantManager = serviceProvider.GetRequiredService(); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); await foreach (var name in variantManager.GetFeatureNamesAsync(cts.Token)) { Console.WriteLine(name); } ``` -------------------------------- ### Checking for a Non-Existent Feature Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/errors.md Example of calling IsEnabledAsync with a feature name that does not exist in the configuration. By default, this throws a FeatureManagementException with the MissingFeature error type. ```csharp var isEnabled = await featureManager.IsEnabledAsync("NonExistentFeature"); // Throws FeatureManagementException with MissingFeature error if not ignored ``` -------------------------------- ### Staged Rollout Patterns Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/SUMMARY.txt Implement staged rollouts for new features, gradually enabling them for a percentage of users. This minimizes risk and allows for monitoring. ```csharp // Configuration example (appsettings.json): // "Features": { // "NewFeature": { // "EnabledFor": [ // { "Name": "Microsoft.Percentage", "Parameters": { "Value": 25 } } // ] // } // } ``` -------------------------------- ### Validate Feature Configuration on Application Startup Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/errors.md Implement IHostedService to validate feature configurations by triggering feature evaluations during application startup. This helps catch configuration errors early. Ensure FeatureManagementException is handled. ```csharp public class FeatureConfigurationValidator : IHostedService { private readonly IFeatureManager _featureManager; private readonly ILogger _logger; public async Task StartAsync(CancellationToken cancellationToken) { try { await foreach (var name in _featureManager.GetFeatureNamesAsync()) { // Trigger evaluation to catch configuration errors early await _featureManager.IsEnabledAsync(name); } _logger.LogInformation("Feature configuration validated successfully"); } catch (FeatureManagementException ex) { _logger.LogError(ex, "Feature configuration is invalid"); throw; } } public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; } ``` -------------------------------- ### ConfigurationFeatureDefinitionProvider Constructor Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureDefinitionProvider.md Initializes a new instance of the ConfigurationFeatureDefinitionProvider class, which reads feature definitions from IConfiguration. ```csharp namespace Microsoft.FeatureManagement; public class ConfigurationFeatureDefinitionProvider : IFeatureDefinitionProvider { public ConfigurationFeatureDefinitionProvider( IConfiguration configuration, ConfigurationFeatureDefinitionProviderOptions options = null) } ``` -------------------------------- ### Get Assigned Variant (Simple) Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IVariantFeatureManager.md Retrieves the assigned variant for a feature when no specific context is provided. Returns a ValueTask which may be null. ```csharp var variant = await variantManager.GetVariantAsync("ExperimentalUI"); if (variant != null) { Console.WriteLine($"Assigned variant: {variant.Name}"); var config = variant.Configuration; } ``` -------------------------------- ### Registering Feature Filters in C# Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/errors.md Demonstrates the correct way to register feature filters using dependency injection. Ensure all custom or required filters are registered to avoid MissingFeatureFilter errors. ```csharp // Register filter before evaluation services.AddFeatureManagement(configuration) .AddFeatureFilter(); // Must register filters // To ignore missing filters: services.Configure(options => { options.IgnoreMissingFeatureFilters = true; }); ``` -------------------------------- ### Register Custom Feature Definition Provider Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/README.md Shows how to implement and register a custom feature definition provider that loads feature definitions from a database. ```csharp public class DatabaseFeatureProvider : IFeatureDefinitionProvider { public async Task GetFeatureDefinitionAsync(string featureName) { // Load from database } public async IAsyncEnumerable GetAllFeatureDefinitionsAsync() { // Load all from database } } services.AddSingleton(); ``` -------------------------------- ### Integration with ASP.NET Core Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/TargetingFilter.md Shows how to register the TargetingFilter and enable HTTP context-based targeting within an ASP.NET Core application's service configuration. ```APIDOC ### Integration with ASP.NET Core #### Register with Targeting Context ```csharp services.AddFeatureManagement(configuration) .AddFeatureFilter() .WithTargeting(); // Enables HTTP context-based targeting ``` ``` -------------------------------- ### Staged Rollout Configuration Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/TargetingFilter.md Configures a feature for staged rollout, targeting specific users and groups with varying percentages. ```json { "FeatureManagement": { "MajorUpdate": { "EnabledFor": [ { "Name": "Microsoft.Targeting", "Parameters": { "Audience": { "Users": ["qa-team@company.com"], "Groups": [ { "Name": "internal", "RolloutPercentage": 100 }, { "Name": "customers", "RolloutPercentage": 10 } ] } } } ] } } } ``` -------------------------------- ### Evaluating Variants with IFeatureManagerSnapshot Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureManagerSnapshot.md Use IFeatureManagerSnapshot to get variant information for a feature. This allows for conditional rendering or behavior based on different experiment variants. ```csharp public async Task ShowExperiment() { var variant = await _featureManager.GetVariantAsync("ExperimentalUI"); return variant?.Name switch { "control" => View("ControlUI"), "variant-a" => View("VariantAUI"), "variant-b" => View("VariantBUI"), null => View("DefaultUI"), _ => View("DefaultUI") }; } ``` -------------------------------- ### Configure Features in appsettings.json Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/README.md Defines feature flags and their enablement conditions, including a percentage-based filter. ```json { "FeatureManagement": { "NewUI": { "Enabled": true }, "BetaFeatures": { "EnabledFor": [ { "Name": "Microsoft.Percentage", "Parameters": { "Value": 25 } } ] } } } ``` -------------------------------- ### Get Assigned Variant (Contextual) Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IVariantFeatureManager.md Retrieves the assigned variant for a feature based on the provided ITargetingContext. This is used for personalized feature experiences or targeted rollouts. ```csharp var context = new TargetingContext { UserId = "user123", Groups = new[] { "beta", "premium" } }; var variant = await variantManager.GetVariantAsync("FeatureX", context); if (variant?.Name == "control") { // User is in control group } else if (variant?.Name == "variant-a") { // User is in variant A } ``` -------------------------------- ### TimeWindowFilter Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureFilter.md The TimeWindowFilter enables a feature during a specific time window, with optional recurrence. It requires 'Start' and 'End' times, and can optionally include recurrence settings. ```APIDOC ## TimeWindowFilter ### Description Enables a feature during a specific time window, with optional recurrence. ### Configuration Example ```json { "MaintenanceMode": { "EnabledFor": [ { "Name": "Microsoft.TimeWindow", "Parameters": { "Start": "2024-06-16T22:00:00Z", "End": "2024-06-17T02:00:00Z", "Recurrence": { "Pattern": "Daily", "Interval": 1 } } } ] } } ``` ### Settings Type `TimeWindowFilterSettings` with `Start`, `End`, and `Recurrence` properties. ``` -------------------------------- ### Instantiate FeatureManager Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/FeatureManager.md Create a new instance of FeatureManager using a feature definition provider and optional options. Ensure the featureDefinitionProvider is not null. ```csharp var provider = new ConfigurationFeatureDefinitionProvider(configuration); var options = new FeatureManagementOptions { IgnoreMissingFeatures = true }; var featureManager = new FeatureManager(provider, options); ``` -------------------------------- ### Add Feature Management (No Configuration) Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/ServiceCollectionExtensions.md Registers feature management services without specifying a configuration source. Use this when configuration is handled elsewhere or not needed initially. ```csharp public static IFeatureManagementBuilder AddFeatureManagement( this IServiceCollection services) ``` -------------------------------- ### Database Integration Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/SUMMARY.txt Integrate feature management with a database for dynamic configuration and feature flag management. This enables real-time updates. ```csharp // Requires a custom configuration provider or a service that fetches flags from the database. ``` -------------------------------- ### Filter Parameters Binding Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureFilter.md Explains how to implement IFilterParametersBinder for handling complex filter parameters by parsing configuration into strongly-typed settings. ```APIDOC ## Filter Parameters Binding ### Implement IFilterParametersBinder For complex parameters, implement `IFilterParametersBinder`: ```csharp public class AdvancedFilter : IFeatureFilter, IFilterParametersBinder { public object BindParameters(IConfiguration filterParameters) { // Parse configuration into strongly-typed settings return filterParameters.Get(); } public Task EvaluateAsync(FeatureFilterEvaluationContext context) { var settings = (AdvancedFilterSettings)context.Settings; return Task.FromResult(EvaluateSettings(settings)); } } ``` ``` -------------------------------- ### Register Feature Management with Custom Options Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/configuration.md Demonstrates how to register Feature Management services while customizing behavior through FeatureManagementOptions. This allows control over ignoring missing features or filters. ```csharp services.AddFeatureManagement(configuration) .Configure(options => { options.IgnoreMissingFeatures = false; options.IgnoreMissingFeatureFilters = true; }); ``` -------------------------------- ### Custom Feature Filter Implementation Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/IFeatureFilter.md Example of implementing a custom feature filter by inheriting from IFeatureFilter and overriding the EvaluateAsync method. Demonstrates accessing parameters and feature name. ```csharp public class CustomFilter : IFeatureFilter { public Task EvaluateAsync(FeatureFilterEvaluationContext context) { // Access configuration var parameters = context.Parameters; // Access feature name var featureName = context.FeatureName; // Implement evaluation logic var value = parameters["CustomValue"]; return Task.FromResult(ShouldEnable(value)); } private bool ShouldEnable(string value) { // Custom logic here return value == "enabled"; } } ``` -------------------------------- ### ConfigurationFeatureDefinitionProviderOptions Class Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/types.md Options for the configuration-based feature definition provider. ```csharp namespace Microsoft.FeatureManagement; public class ConfigurationFeatureDefinitionProviderOptions { // Configuration options for feature definitions } ``` -------------------------------- ### Using Open Iconic Font with Foundation Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/examples/BlazorServerApp/wwwroot/css/open-iconic/README.md Apply Open Iconic icons in Foundation projects by using the 'fi' class and the specific icon name. ```html ``` -------------------------------- ### Configuring IgnoreMissingFeatures Option Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/errors.md Demonstrates how to configure the Feature Management options to either ignore missing features (return false) or throw an exception. The default behavior is to ignore them. ```csharp services.Configure(options => { // Default: true - missing features return false instead of throwing options.IgnoreMissingFeatures = true; // Set to false to throw exception options.IgnoreMissingFeatures = false; }); ``` -------------------------------- ### Graceful Degradation for Feature Evaluation Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/errors.md An example of a graceful degradation pattern where feature evaluation is wrapped in a try-catch block. If an exception occurs, it logs the error and returns a predefined default value based on the feature's criticality. ```csharp public async Task GetFeatureStateAsync(string featureName) { try { return await featureManager.IsEnabledAsync(featureName); } catch (FeatureManagementException ex) { logger.LogError(ex, $"Feature evaluation failed for {featureName}"); // Return safe default return featureName switch { "CriticalFeature" => true, // Default to enabled for critical features _ => false // Default to disabled for others }; } } ``` -------------------------------- ### Add Feature Management with Configuration Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/ServiceCollectionExtensions.md Registers feature management services using a provided IConfiguration instance. This is useful for loading feature flags and settings from configuration sources. ```csharp public static IFeatureManagementBuilder AddFeatureManagement( this IServiceCollection services, IConfiguration configuration) ``` -------------------------------- ### Targeting Filter Configuration with Rollout Percentage Source: https://github.com/microsoft/featuremanagement-dotnet/blob/main/_autodocs/api-reference/TargetingFilter.md Illustrates how to configure the TargetingFilter to enable a feature for a specific percentage of users within a group. This is defined in the feature flag's JSON configuration. ```json { "Groups": [ { "Name": "customers", "RolloutPercentage": 10 } ] } ```