Indiko.Blocks.API.FeatureManagement 2.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Indiko.Blocks.API.FeatureManagement --version 2.1.0
                    
NuGet\Install-Package Indiko.Blocks.API.FeatureManagement -Version 2.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Indiko.Blocks.API.FeatureManagement" Version="2.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Indiko.Blocks.API.FeatureManagement" Version="2.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Indiko.Blocks.API.FeatureManagement" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Indiko.Blocks.API.FeatureManagement --version 2.1.0
                    
#r "nuget: Indiko.Blocks.API.FeatureManagement, 2.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Indiko.Blocks.API.FeatureManagement@2.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Indiko.Blocks.API.FeatureManagement&version=2.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Indiko.Blocks.API.FeatureManagement&version=2.1.0
                    
Install as a Cake Tool

Indiko.Blocks.API.FeatureManagement

Feature flag management block for controlling feature rollouts, A/B testing, and gradual deployments using Microsoft Feature Management.

Overview

This package provides feature flag (feature toggle) support for ASP.NET Core APIs, enabling dynamic feature control without code deployments.

Features

  • Feature Flags: Enable/disable features dynamically
  • Conditional Features: Context-based feature activation
  • A/B Testing: Percentage-based feature rollouts
  • Targeting: User/group-specific features
  • Time Windows: Schedule feature availability
  • MVC Integration: Feature-aware controllers and actions
  • IFeatureManager: Programmatic feature checks
  • Configuration-Based: Define features in appsettings.json

Installation

dotnet add package Indiko.Blocks.API.FeatureManagement

Quick Start

Configuration (appsettings.json)

{
  "FeatureManagement": {
    "NewUserInterface": true,
    "BetaFeatures": false,
    "PremiumFeatures": {
      "EnabledFor": [
        {
          "Name": "Percentage",
          "Parameters": {
            "Value": 50
          }
        }
      ]
    }
  }
}

Basic Usage

Check Features in Code

using Microsoft.FeatureManagement;

public class ProductsController : ControllerBase
{
    private readonly IFeatureManager _featureManager;

    public ProductsController(IFeatureManager featureManager)
    {
        _featureManager = featureManager;
    }

    [HttpGet]
    public async Task<IActionResult> GetProducts()
    {
        if (await _featureManager.IsEnabledAsync("NewUserInterface"))
        {
            return Ok(await GetProductsWithNewUI());
        }
        
        return Ok(await GetProductsWithOldUI());
    }
}

Feature Gates on Actions

using Microsoft.FeatureManagement.Mvc;

[ApiController]
[Route("api/[controller]")]
public class BetaController : ControllerBase
{
    [HttpGet]
    [FeatureGate("BetaFeatures")]  // Only accessible if BetaFeatures is enabled
    public IActionResult GetBetaFeature()
    {
        return Ok("Beta feature data");
    }
}

Feature Types

Simple Boolean Flags

{
  "FeatureManagement": {
    "DarkMode": true,
    "MaintenanceMode": false
  }
}
if (await _featureManager.IsEnabledAsync("DarkMode"))
{
    // Apply dark mode
}

Percentage Rollout (A/B Testing)

{
  "FeatureManagement": {
    "NewCheckout": {
      "EnabledFor": [
        {
          "Name": "Percentage",
          "Parameters": {
            "Value": 25  // 25% of users see new checkout
          }
        }
      ]
    }
  }
}

Time Window Features

{
  "FeatureManagement": {
    "HolidaySale": {
      "EnabledFor": [
        {
          "Name": "TimeWindow",
          "Parameters": {
            "Start": "2024-12-20T00:00:00Z",
            "End": "2024-12-26T23:59:59Z"
          }
        }
      ]
    }
  }
}

User Targeting

{
  "FeatureManagement": {
    "PremiumFeatures": {
      "EnabledFor": [
        {
          "Name": "TargetingFilter",
          "Parameters": {
            "Audience": {
              "Users": [
                "user1@example.com",
                "user2@example.com"
              ],
              "Groups": [
                "premium",
                "beta-testers"
              ]
            }
          }
        }
      ]
    }
  }
}

Feature Filters

Built-in Filters

  1. Percentage Filter: Gradual rollout based on percentage
  2. Time Window Filter: Time-based activation
  3. Targeting Filter: User/group-based activation

Custom Feature Filter

using Microsoft.FeatureManagement;

[FilterAlias("Environment")]
public class EnvironmentFeatureFilter : IFeatureFilter
{
    private readonly IWebHostEnvironment _environment;

    public EnvironmentFeatureFilter(IWebHostEnvironment environment)
    {
        _environment = environment;
    }

    public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context)
    {
        var settings = context.Parameters.Get<EnvironmentFilterSettings>();
        return Task.FromResult(settings.Environments.Contains(_environment.EnvironmentName));
    }
}

public class EnvironmentFilterSettings
{
    public string[] Environments { get; set; }
}

// Register
services.AddFeatureManagement()
    .AddFeatureFilter<EnvironmentFeatureFilter>();

// Use in config
{
  "FeatureManagement": {
    "DebugTools": {
      "EnabledFor": [
        {
          "Name": "Environment",
          "Parameters": {
            "Environments": ["Development", "Staging"]
          }
        }
      ]
    }
  }
}

Controller-Level Gates

[ApiController]
[Route("api/[controller]")]
[FeatureGate("AdminPanel")]  // Entire controller requires feature
public class AdminController : ControllerBase
{
    [HttpGet("users")]
    public IActionResult GetUsers() => Ok(users);
    
    [HttpGet("settings")]
    [FeatureGate("AdvancedSettings")]  // Additional feature requirement
    public IActionResult GetSettings() => Ok(settings);
}

Middleware Integration

public class FeatureCheckMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IFeatureManager _featureManager;

    public FeatureCheckMiddleware(RequestDelegate next, IFeatureManager featureManager)
    {
        _next = next;
        _featureManager = featureManager;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        if (context.Request.Path.StartsWithSegments("/api/beta"))
        {
            if (!await _featureManager.IsEnabledAsync("BetaAccess"))
            {
                context.Response.StatusCode = 403;
                await context.Response.WriteAsync("Beta access not available");
                return;
            }
        }
        
        await _next(context);
    }
}

Service Layer

public class ProductService
{
    private readonly IFeatureManager _featureManager;
    private readonly IProductRepository _repository;

    public async Task<ProductDto> GetProductAsync(Guid id)
    {
        var product = await _repository.ReadByIdAsync(id);
        
        if (await _featureManager.IsEnabledAsync("EnhancedProductDetails"))
        {
            product.AdditionalDetails = await LoadEnhancedDetails(id);
        }
        
        return product;
    }
}

Configuration Sources

AppSettings

{
  "FeatureManagement": {
    "Feature1": true
  }
}

Environment Variables

export FeatureManagement__Feature1=true

Azure App Configuration

services.AddAzureAppConfiguration(options =>
{
    options.Connect(connectionString)
           .UseFeatureFlags();
});

Best Practices

  1. Naming: Use descriptive names (NewCheckoutFlow, EnhancedSearch)
  2. Cleanup: Remove feature flags once fully rolled out
  3. Testing: Test both enabled and disabled states
  4. Documentation: Document what each feature flag controls
  5. Monitoring: Track feature usage and performance
  6. Gradual Rollout: Start with small percentages
  7. Fallbacks: Always have fallback logic

Deployment Strategies

Canary Deployment

{
  "FeatureManagement": {
    "NewPaymentGateway": {
      "EnabledFor": [
        {
          "Name": "Percentage",
          "Parameters": { "Value": 5 }  // Start with 5%
        }
      ]
    }
  }
}

Monitor, then increase: 5% ? 25% ? 50% ? 100%

Blue-Green Deployment

{
  "FeatureManagement": {
    "UseNewDatabase": false  // Toggle between old/new
  }
}

Testing

Unit Testing

[Fact]
public async Task GetProducts_WithNewUI_ReturnsEnhancedData()
{
    // Arrange
    var featureManagerMock = new Mock<IFeatureManager>();
    featureManagerMock
        .Setup(x => x.IsEnabledAsync("NewUserInterface", It.IsAny<CancellationToken>()))
        .ReturnsAsync(true);
    
    var controller = new ProductsController(featureManagerMock.Object);
    
    // Act
    var result = await controller.GetProducts();
    
    // Assert
    Assert.IsType<OkObjectResult>(result);
}

Target Framework

  • .NET 10

Dependencies

  • Microsoft.FeatureManagement.AspNetCore (3.0+)
  • Indiko.Blocks.Common.Abstractions

License

See LICENSE file in the repository root.

  • Indiko.Blocks.API.Swagger - API documentation
  • Indiko.Blocks.API.Compression - Response compression
  • Microsoft.FeatureManagement - Core feature management
  • Microsoft.FeatureManagement.AspNetCore - ASP.NET Core integration

Resources

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.2 224 12/18/2025
2.1.1 618 12/2/2025
2.1.0 615 12/2/2025
2.0.0 268 9/17/2025
1.7.23 179 9/8/2025
1.7.22 170 9/8/2025
1.7.21 186 8/14/2025
1.7.20 179 6/23/2025
1.7.19 179 6/3/2025
1.7.18 174 5/29/2025
1.7.17 177 5/26/2025
1.7.15 127 4/12/2025
1.7.14 156 4/11/2025
1.7.13 145 3/29/2025
1.7.12 160 3/28/2025
1.7.11 160 3/28/2025
1.7.10 160 3/28/2025
1.7.9 156 3/28/2025
1.7.8 148 3/28/2025
1.7.5 176 3/17/2025
1.7.4 178 3/16/2025
1.7.3 172 3/16/2025
1.7.2 165 3/16/2025
1.7.1 218 3/11/2025
1.6.8 213 3/11/2025
1.6.7 242 3/4/2025
1.6.6 138 2/26/2025
1.6.5 122 2/20/2025
1.6.4 140 2/20/2025
1.6.3 146 2/5/2025
1.6.2 132 1/24/2025
1.6.1 139 1/24/2025
1.6.0 134 1/16/2025
1.5.2 124 1/16/2025
1.5.1 154 11/3/2024
1.5.0 139 10/26/2024
1.3.2 139 10/24/2024
1.3.0 138 10/10/2024
1.2.5 147 10/9/2024
1.2.4 143 10/8/2024
1.2.1 141 10/3/2024
1.2.0 147 9/29/2024
1.1.1 145 9/23/2024
1.1.0 147 9/18/2024
1.0.33 165 9/15/2024
1.0.28 160 8/28/2024
1.0.27 176 8/24/2024
1.0.26 162 7/7/2024
1.0.25 145 7/6/2024
1.0.24 162 6/25/2024
1.0.23 155 6/1/2024
1.0.22 157 5/14/2024
1.0.21 143 5/14/2024
1.0.20 156 4/8/2024
1.0.19 167 4/3/2024
1.0.18 178 3/23/2024
1.0.17 186 3/19/2024
1.0.16 177 3/19/2024
1.0.15 172 3/11/2024
1.0.14 166 3/10/2024
1.0.13 168 3/6/2024
1.0.12 194 3/1/2024
1.0.11 191 3/1/2024
1.0.10 172 3/1/2024
1.0.9 174 3/1/2024
1.0.8 162 2/19/2024
1.0.7 170 2/17/2024
1.0.6 166 2/17/2024
1.0.5 156 2/17/2024
1.0.4 169 2/7/2024
1.0.3 161 2/6/2024
1.0.1 152 2/6/2024
1.0.0 196 1/9/2024
1.0.0-preview99 185 12/22/2023
1.0.0-preview98 139 12/21/2023
1.0.0-preview97 151 12/21/2023
1.0.0-preview96 138 12/20/2023
1.0.0-preview94 144 12/18/2023
1.0.0-preview93 156 12/13/2023
1.0.0-preview92 164 12/13/2023
1.0.0-preview91 165 12/12/2023
1.0.0-preview90 149 12/11/2023
1.0.0-preview89 156 12/11/2023
1.0.0-preview88 151 12/6/2023
1.0.0-preview87 145 12/6/2023
1.0.0-preview86 161 12/6/2023
1.0.0-preview85 158 12/6/2023
1.0.0-preview84 163 12/5/2023
1.0.0-preview83 144 12/5/2023
1.0.0-preview82 145 12/5/2023
1.0.0-preview81 152 12/4/2023
1.0.0-preview80 152 12/1/2023
1.0.0-preview77 156 12/1/2023
1.0.0-preview76 154 12/1/2023
1.0.0-preview75 152 12/1/2023
1.0.0-preview74 149 11/26/2023
1.0.0-preview73 161 11/7/2023
1.0.0-preview72 145 11/6/2023
1.0.0-preview71 160 11/3/2023
1.0.0-preview70 155 11/2/2023
1.0.0-preview69 145 11/2/2023
1.0.0-preview68 147 11/2/2023
1.0.0-preview67 150 11/2/2023
1.0.0-preview66 137 11/2/2023
1.0.0-preview65 149 11/2/2023
1.0.0-preview64 158 11/2/2023
1.0.0-preview63 145 11/2/2023
1.0.0-preview62 146 11/1/2023
1.0.0-preview61 153 11/1/2023
1.0.0-preview60 146 11/1/2023
1.0.0-preview59 147 11/1/2023
1.0.0-preview58 144 10/31/2023
1.0.0-preview57 141 10/31/2023
1.0.0-preview56 143 10/31/2023
1.0.0-preview55 138 10/31/2023
1.0.0-preview54 134 10/31/2023
1.0.0-preview53 135 10/31/2023
1.0.0-preview52 124 10/31/2023
1.0.0-preview51 127 10/31/2023
1.0.0-preview50 150 10/31/2023
1.0.0-preview48 151 10/31/2023
1.0.0-preview46 148 10/31/2023
1.0.0-preview45 140 10/31/2023
1.0.0-preview44 142 10/31/2023
1.0.0-preview43 142 10/31/2023
1.0.0-preview42 154 10/30/2023
1.0.0-preview41 162 10/30/2023
1.0.0-preview101 140 1/5/2024