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 226 12/18/2025
2.1.1 619 12/2/2025
2.1.0 616 12/2/2025
2.0.0 269 9/17/2025
1.7.23 180 9/8/2025
1.7.22 172 9/8/2025
1.7.21 187 8/14/2025
1.7.20 179 6/23/2025
1.7.19 181 6/3/2025
1.7.18 174 5/29/2025
1.7.17 178 5/26/2025
1.7.15 128 4/12/2025
1.7.14 157 4/11/2025
1.7.13 145 3/29/2025
1.7.12 161 3/28/2025
1.7.11 160 3/28/2025
1.7.10 162 3/28/2025
1.7.9 156 3/28/2025
1.7.8 150 3/28/2025
1.7.5 177 3/17/2025
1.7.4 178 3/16/2025
1.7.3 174 3/16/2025
1.7.2 165 3/16/2025
1.7.1 219 3/11/2025
1.6.8 214 3/11/2025
1.6.7 243 3/4/2025
1.6.6 140 2/26/2025
1.6.5 123 2/20/2025
1.6.4 141 2/20/2025
1.6.3 147 2/5/2025
1.6.2 132 1/24/2025
1.6.1 141 1/24/2025
1.6.0 135 1/16/2025
1.5.2 125 1/16/2025
1.5.1 156 11/3/2024
1.5.0 140 10/26/2024
1.3.2 139 10/24/2024
1.3.0 138 10/10/2024
1.2.5 148 10/9/2024
1.2.4 144 10/8/2024
1.2.1 142 10/3/2024
1.2.0 148 9/29/2024
1.1.1 147 9/23/2024
1.1.0 148 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 163 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 158 5/14/2024
1.0.21 144 5/14/2024
1.0.20 158 4/8/2024
1.0.19 167 4/3/2024
1.0.18 179 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 195 3/1/2024
1.0.11 191 3/1/2024
1.0.10 172 3/1/2024
1.0.9 175 3/1/2024
1.0.8 162 2/19/2024
1.0.7 171 2/17/2024
1.0.6 166 2/17/2024
1.0.5 158 2/17/2024
1.0.4 170 2/7/2024
1.0.3 161 2/6/2024
1.0.1 153 2/6/2024
1.0.0 197 1/9/2024
1.0.0-preview99 187 12/22/2023
1.0.0-preview98 140 12/21/2023
1.0.0-preview97 152 12/21/2023
1.0.0-preview96 140 12/20/2023
1.0.0-preview94 145 12/18/2023
1.0.0-preview93 156 12/13/2023
1.0.0-preview92 165 12/13/2023
1.0.0-preview91 166 12/12/2023
1.0.0-preview90 149 12/11/2023
1.0.0-preview89 158 12/11/2023
1.0.0-preview88 152 12/6/2023
1.0.0-preview87 145 12/6/2023
1.0.0-preview86 162 12/6/2023
1.0.0-preview85 160 12/6/2023
1.0.0-preview84 165 12/5/2023
1.0.0-preview83 144 12/5/2023
1.0.0-preview82 145 12/5/2023
1.0.0-preview81 153 12/4/2023
1.0.0-preview80 154 12/1/2023
1.0.0-preview77 156 12/1/2023
1.0.0-preview76 155 12/1/2023
1.0.0-preview75 153 12/1/2023
1.0.0-preview74 150 11/26/2023
1.0.0-preview73 162 11/7/2023
1.0.0-preview72 147 11/6/2023
1.0.0-preview71 160 11/3/2023
1.0.0-preview70 157 11/2/2023
1.0.0-preview69 146 11/2/2023
1.0.0-preview68 149 11/2/2023
1.0.0-preview67 150 11/2/2023
1.0.0-preview66 139 11/2/2023
1.0.0-preview65 149 11/2/2023
1.0.0-preview64 158 11/2/2023
1.0.0-preview63 146 11/2/2023
1.0.0-preview62 147 11/1/2023
1.0.0-preview61 154 11/1/2023
1.0.0-preview60 147 11/1/2023
1.0.0-preview59 148 11/1/2023
1.0.0-preview58 144 10/31/2023
1.0.0-preview57 142 10/31/2023
1.0.0-preview56 143 10/31/2023
1.0.0-preview55 139 10/31/2023
1.0.0-preview54 134 10/31/2023
1.0.0-preview53 136 10/31/2023
1.0.0-preview52 124 10/31/2023
1.0.0-preview51 128 10/31/2023
1.0.0-preview50 150 10/31/2023
1.0.0-preview48 153 10/31/2023
1.0.0-preview46 148 10/31/2023
1.0.0-preview45 141 10/31/2023
1.0.0-preview44 143 10/31/2023
1.0.0-preview43 142 10/31/2023
1.0.0-preview42 155 10/30/2023
1.0.0-preview41 162 10/30/2023
1.0.0-preview101 141 1/5/2024