Indiko.Blocks.API.FeatureManagement
2.1.0
There is a newer version of this package available.
See the version list below for details.
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" />
<PackageReference Include="Indiko.Blocks.API.FeatureManagement" />
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
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#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
#tool nuget:?package=Indiko.Blocks.API.FeatureManagement&version=2.1.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
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
- Percentage Filter: Gradual rollout based on percentage
- Time Window Filter: Time-based activation
- 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
- Naming: Use descriptive names (NewCheckoutFlow, EnhancedSearch)
- Cleanup: Remove feature flags once fully rolled out
- Testing: Test both enabled and disabled states
- Documentation: Document what each feature flag controls
- Monitoring: Track feature usage and performance
- Gradual Rollout: Start with small percentages
- 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.
Related Packages
Indiko.Blocks.API.Swagger- API documentationIndiko.Blocks.API.Compression- Response compressionMicrosoft.FeatureManagement- Core feature managementMicrosoft.FeatureManagement.AspNetCore- ASP.NET Core integration
Resources
| Product | Versions 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.
-
net10.0
- Indiko.Blocks.Common.Abstractions (>= 2.1.0)
- Microsoft.Data.SqlClient (>= 7.0.0-preview1.25257.1)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.0)
- Microsoft.FeatureManagement.AspNetCore (>= 4.3.0)
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 |