Indiko.Blocks.API.FeatureManagement 2.1.2

dotnet add package Indiko.Blocks.API.FeatureManagement --version 2.1.2
                    
NuGet\Install-Package Indiko.Blocks.API.FeatureManagement -Version 2.1.2
                    
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.2" />
                    
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.2" />
                    
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.2
                    
#r "nuget: Indiko.Blocks.API.FeatureManagement, 2.1.2"
                    
#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.2
                    
#: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.2
                    
Install as a Cake Addin
#tool nuget:?package=Indiko.Blocks.API.FeatureManagement&version=2.1.2
                    
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 243 12/18/2025
2.1.1 634 12/2/2025
2.1.0 624 12/2/2025
2.0.0 284 9/17/2025
1.7.23 192 9/8/2025
1.7.22 180 9/8/2025
1.7.21 199 8/14/2025
1.7.20 191 6/23/2025
1.7.19 194 6/3/2025
1.7.18 186 5/29/2025
1.7.17 187 5/26/2025
1.7.15 140 4/12/2025
1.7.14 165 4/11/2025
1.7.13 160 3/29/2025
1.7.12 175 3/28/2025
1.7.11 175 3/28/2025
1.7.10 177 3/28/2025
1.7.9 168 3/28/2025
1.7.8 166 3/28/2025
1.7.5 187 3/17/2025
1.7.4 190 3/16/2025
1.7.3 190 3/16/2025
1.7.2 175 3/16/2025
1.7.1 230 3/11/2025
1.6.8 228 3/11/2025
1.6.7 260 3/4/2025
1.6.6 150 2/26/2025
1.6.5 139 2/20/2025
1.6.4 155 2/20/2025
1.6.3 160 2/5/2025
1.6.2 141 1/24/2025
1.6.1 156 1/24/2025
1.6.0 153 1/16/2025
1.5.2 146 1/16/2025
1.5.1 175 11/3/2024
1.5.0 152 10/26/2024
1.3.2 147 10/24/2024
1.3.0 148 10/10/2024
1.2.5 160 10/9/2024
1.2.4 155 10/8/2024
1.2.1 155 10/3/2024
1.2.0 157 9/29/2024
1.1.1 158 9/23/2024
1.1.0 162 9/18/2024
1.0.33 180 9/15/2024
1.0.28 167 8/28/2024
1.0.27 197 8/24/2024
1.0.26 175 7/7/2024
1.0.25 154 7/6/2024
1.0.24 171 6/25/2024
1.0.23 167 6/1/2024
1.0.22 168 5/14/2024
1.0.21 156 5/14/2024
1.0.20 173 4/8/2024
1.0.19 181 4/3/2024
1.0.18 195 3/23/2024
1.0.17 198 3/19/2024
1.0.16 186 3/19/2024
1.0.15 182 3/11/2024
1.0.14 173 3/10/2024
1.0.13 179 3/6/2024
1.0.12 207 3/1/2024
1.0.11 204 3/1/2024
1.0.10 185 3/1/2024
1.0.9 187 3/1/2024
1.0.8 174 2/19/2024
1.0.7 190 2/17/2024
1.0.6 178 2/17/2024
1.0.5 176 2/17/2024
1.0.4 183 2/7/2024
1.0.3 174 2/6/2024
1.0.1 163 2/6/2024
1.0.0 206 1/9/2024
1.0.0-preview99 200 12/22/2023
1.0.0-preview98 148 12/21/2023
1.0.0-preview97 164 12/21/2023
1.0.0-preview96 152 12/20/2023
1.0.0-preview94 154 12/18/2023
1.0.0-preview93 164 12/13/2023
1.0.0-preview92 177 12/13/2023
1.0.0-preview91 180 12/12/2023
1.0.0-preview90 161 12/11/2023
1.0.0-preview89 171 12/11/2023
1.0.0-preview88 165 12/6/2023
1.0.0-preview87 155 12/6/2023
1.0.0-preview86 174 12/6/2023
1.0.0-preview85 169 12/6/2023
1.0.0-preview84 177 12/5/2023
1.0.0-preview83 153 12/5/2023
1.0.0-preview82 159 12/5/2023
1.0.0-preview81 170 12/4/2023
1.0.0-preview80 167 12/1/2023
1.0.0-preview77 167 12/1/2023
1.0.0-preview76 164 12/1/2023
1.0.0-preview75 164 12/1/2023
1.0.0-preview74 162 11/26/2023
1.0.0-preview73 176 11/7/2023
1.0.0-preview72 161 11/6/2023
1.0.0-preview71 174 11/3/2023
1.0.0-preview70 166 11/2/2023
1.0.0-preview69 153 11/2/2023
1.0.0-preview68 157 11/2/2023
1.0.0-preview67 161 11/2/2023
1.0.0-preview66 149 11/2/2023
1.0.0-preview65 159 11/2/2023
1.0.0-preview64 167 11/2/2023
1.0.0-preview63 158 11/2/2023
1.0.0-preview62 157 11/1/2023
1.0.0-preview61 168 11/1/2023
1.0.0-preview60 159 11/1/2023
1.0.0-preview59 159 11/1/2023
1.0.0-preview58 156 10/31/2023
1.0.0-preview57 156 10/31/2023
1.0.0-preview56 152 10/31/2023
1.0.0-preview55 154 10/31/2023
1.0.0-preview54 148 10/31/2023
1.0.0-preview53 145 10/31/2023
1.0.0-preview52 137 10/31/2023
1.0.0-preview51 140 10/31/2023
1.0.0-preview50 162 10/31/2023
1.0.0-preview48 166 10/31/2023
1.0.0-preview46 159 10/31/2023
1.0.0-preview45 158 10/31/2023
1.0.0-preview44 156 10/31/2023
1.0.0-preview43 155 10/31/2023
1.0.0-preview42 169 10/30/2023
1.0.0-preview41 172 10/30/2023
1.0.0-preview101 148 1/5/2024