.NET Feature Management

repository·main·Indexed 22 days ago

https://github.com/microsoft/featuremanagement-dotnet

.NET Feature Management allows developers to develop and expose application functionality based on features and defined conditions. It supports scoped registration for Blazor Server apps, custom IFeatureDefinitionProvider implementations using ParametersObject, and variant service resolution via IVariantServiceProvider<T> for A/B testing. The library integrates with Azure Application Insights for monitoring feature evaluation telemetry and supports targeting filters based on user identity and browser information.

Tokens
6K
Snippets
24
Records
30
Agent score
79%

What's inside microsoft-featuremanagement-dotnet

  1. Implement a Targeting Id for telemetry correlation

    main

    To connect feature evaluation events with specific user metrics, you should emit a TargetingId. The recommended pattern is to use a Telemetry Initializer to modify all outgoing telemetry before it is sent.

    In the provided demo pattern:

    1. Use TargetingHttpContextMiddleware to add a TargetingId (retrieved via a targeting context accessor) to the HttpContext for every incoming request.
    2. Use a TargetingTelemetryInitializer to check the HttpContext for the presence of a TargetingId. If found, the initializer appends this ID to all outgoing Application Insights telemetry, allowing you to group feature evaluations by user.
  2. Handle HttpContext and Targeting Context in Blazor Server

    main

    In Blazor Server apps with interactive rendering, IHttpContextAccessor should be avoided because a valid HttpContext is not available during interactive sessions.

    To use data from the HttpContext (such as the User-Agent for browser-based feature filters) in feature evaluation, follow this pattern:

    1. Capture the required data from HttpContext during the initial request.
    2. Copy that data into a scoped service (e.g., a UserAgentContext service).
    3. Inject that scoped service into your custom feature filters via dependency injection.
  3. Register Feature Management in Blazor Server Apps

    main

    When using Feature Management in a Blazor Server application, you must register the services as scoped rather than singleton. This is because Blazor apps rely on ambient contextual data (like user authentication state or browser information) that is provided via scoped services. Registering as a singleton will break the ability to access this context.

    Avoid: services.AddFeatureManagement()

    Use: services.AddScopedFeatureManagement()

    services.AddScopedFeatureManagement();
  4. Explore .NET Feature Management examples

    main

    The repository contains several implementation examples for different application types and feature scenarios:

    • Console Applications: Basic usage (./examples/ConsoleApp) and usage with Targeting (./examples/TargetingConsoleApp).
    • ASP.NET Core Web Apps: Razor Pages (./examples/RazorPages), MVC (./examples/FeatureFlagDemo), and advanced scenarios involving Variants and Telemetry (./examples/VariantAndTelemetryDemo) or a Variant Service (./examples/VariantServiceDemo).
    • Blazor: Blazor Server App (./examples/BlazorServerApp).
  5. Analyze A/B testing results with Application Insights

    main

    When telemetry.enabled is set to true in your feature flag configuration, feature evaluation data is sent to Application Insights. You can use Kusto (KQL) queries to compare performance metrics (like request duration) between different variants.

    Use the following query in the Application Insights Logs blade to compare the average duration of requests per variant, joined by the TargetingId:

    customEvents
    | where name == "FeatureEvaluation"
    | project TargetingId = tostring(customDimensions.TargetingId), Variant = tostring(customDimensions.Variant)
    | join (
        requests
        | where url matches regex @"https://localhost:\d+/Index\?handler=Calculate"
        | project TargetingId = tostring(customDimensions.TargetingId), Duration = todouble(duration)
      ) on TargetingId
    | project TargetingId, Variant, Duration
    | summarize Duration = avg(Duration) by Variant
  6. Use ParametersObject to supply filter settings in custom IFeatureDefinitionProvider

    main

    When implementing a custom IFeatureDefinitionProvider to source feature definitions from external backends (such as databases or REST APIs), you can use the ParametersObject property on FeatureFilterConfiguration to provide filter settings.

    This approach allows you to assign strongly-typed settings objects (e.g., TargetingFilterSettings) directly to the configuration, bypassing the need to construct a complex IConfiguration object using magic string keys.

    new FeatureFilterConfiguration
    {
        Name = "Microsoft.Targeting",
        ParametersObject = new TargetingFilterSettings
        {
            Audience = new Audience
            {
                Users = new List<string> { "Jeff", "Anne" },
                Groups = new List<GroupRollout> { /* ... */ },
                DefaultRolloutPercentage = 20
            }
        }
    }
  7. Send Feature Evaluation Data to Application Insights

    main

    You can monitor feature flag evaluations by sending telemetry to Azure Application Insights. Evaluation data is emitted every time a feature result is determined by the FeatureManager.

    To enable this in your application, you must provide an Application Insights connection string in your configuration. The telemetry includes details such as the FeatureName, the Variant selected, whether the feature IsEnabled, and any associated Tags or Label.

    {
      "ApplicationInsights": {
        "ConnectionString": "YOUR_CONNECTION_STRING"
      }
    }
  8. Connect your application to Application Insights

    main

    To flow feature evaluation events to an Azure Application Insights resource:

    1. Create a new Application Insights resource in the Azure Portal.
    2. Copy the Connection String from the resource's Overview page.
    3. Add the connection string to your appsettings.json file under the ApplicationInsights section using the key ConnectionString.
    4. Restart your application.

    If no connection string is provided, the telemetry will still be visible in the IDE's Output window (labeled as Application Insights Telemetry) for debugging purposes.