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.1 611 12/2/2025
2.1.0 611 12/2/2025
2.0.0 264 9/17/2025
1.7.23 173 9/8/2025
1.7.22 166 9/8/2025
1.7.21 179 8/14/2025
1.7.20 173 6/23/2025
1.7.19 175 6/3/2025
1.7.18 167 5/29/2025
1.7.17 172 5/26/2025
1.7.15 124 4/12/2025
1.7.14 152 4/11/2025
1.7.13 139 3/29/2025
1.7.12 154 3/28/2025
1.7.11 154 3/28/2025
1.7.10 156 3/28/2025
1.7.9 154 3/28/2025
1.7.8 144 3/28/2025
1.7.5 172 3/17/2025
1.7.4 173 3/16/2025
1.7.3 167 3/16/2025
1.7.2 162 3/16/2025
1.7.1 213 3/11/2025
1.6.8 208 3/11/2025
1.6.7 238 3/4/2025
1.6.6 135 2/26/2025
1.6.5 117 2/20/2025
1.6.4 135 2/20/2025
1.6.3 143 2/5/2025
1.6.2 130 1/24/2025
1.6.1 133 1/24/2025
1.6.0 126 1/16/2025
1.5.2 121 1/16/2025
1.5.1 150 11/3/2024
1.5.0 135 10/26/2024
1.3.2 136 10/24/2024
1.3.0 134 10/10/2024
1.2.5 143 10/9/2024
1.2.4 138 10/8/2024
1.2.1 138 10/3/2024
1.2.0 145 9/29/2024
1.1.1 138 9/23/2024
1.1.0 143 9/18/2024
1.0.33 163 9/15/2024
1.0.28 159 8/28/2024
1.0.27 171 8/24/2024
1.0.26 161 7/7/2024
1.0.25 143 7/6/2024
1.0.24 160 6/25/2024
1.0.23 154 6/1/2024
1.0.22 153 5/14/2024
1.0.21 143 5/14/2024
1.0.20 156 4/8/2024
1.0.19 163 4/3/2024
1.0.18 174 3/23/2024
1.0.17 182 3/19/2024
1.0.16 173 3/19/2024
1.0.15 171 3/11/2024
1.0.14 163 3/10/2024
1.0.13 167 3/6/2024
1.0.12 192 3/1/2024
1.0.11 188 3/1/2024
1.0.10 170 3/1/2024
1.0.9 170 3/1/2024
1.0.8 158 2/19/2024
1.0.7 166 2/17/2024
1.0.6 162 2/17/2024
1.0.5 154 2/17/2024
1.0.4 167 2/7/2024
1.0.3 159 2/6/2024
1.0.1 150 2/6/2024
1.0.0 194 1/9/2024
1.0.0-preview99 180 12/22/2023
1.0.0-preview98 138 12/21/2023
1.0.0-preview97 148 12/21/2023
1.0.0-preview96 134 12/20/2023
1.0.0-preview94 142 12/18/2023
1.0.0-preview93 155 12/13/2023
1.0.0-preview92 160 12/13/2023
1.0.0-preview91 164 12/12/2023
1.0.0-preview90 147 12/11/2023
1.0.0-preview89 152 12/11/2023
1.0.0-preview88 149 12/6/2023
1.0.0-preview87 139 12/6/2023
1.0.0-preview86 160 12/6/2023
1.0.0-preview85 157 12/6/2023
1.0.0-preview84 159 12/5/2023
1.0.0-preview83 143 12/5/2023
1.0.0-preview82 141 12/5/2023
1.0.0-preview81 150 12/4/2023
1.0.0-preview80 147 12/1/2023
1.0.0-preview77 154 12/1/2023
1.0.0-preview76 153 12/1/2023
1.0.0-preview75 148 12/1/2023
1.0.0-preview74 147 11/26/2023
1.0.0-preview73 160 11/7/2023
1.0.0-preview72 141 11/6/2023
1.0.0-preview71 156 11/3/2023
1.0.0-preview70 155 11/2/2023
1.0.0-preview69 143 11/2/2023
1.0.0-preview68 145 11/2/2023
1.0.0-preview67 148 11/2/2023
1.0.0-preview66 133 11/2/2023
1.0.0-preview65 145 11/2/2023
1.0.0-preview64 155 11/2/2023
1.0.0-preview63 145 11/2/2023
1.0.0-preview62 145 11/1/2023
1.0.0-preview61 149 11/1/2023
1.0.0-preview60 144 11/1/2023
1.0.0-preview59 146 11/1/2023
1.0.0-preview58 142 10/31/2023
1.0.0-preview57 137 10/31/2023
1.0.0-preview56 142 10/31/2023
1.0.0-preview55 135 10/31/2023
1.0.0-preview54 132 10/31/2023
1.0.0-preview53 134 10/31/2023
1.0.0-preview52 124 10/31/2023
1.0.0-preview51 124 10/31/2023
1.0.0-preview50 147 10/31/2023
1.0.0-preview48 147 10/31/2023
1.0.0-preview46 146 10/31/2023
1.0.0-preview45 138 10/31/2023
1.0.0-preview44 139 10/31/2023
1.0.0-preview43 141 10/31/2023
1.0.0-preview42 151 10/30/2023
1.0.0-preview41 155 10/30/2023
1.0.0-preview101 137 1/5/2024