DNV.Dapr.FeatureManagement
2.1.0-preview.1756698443
dotnet add package DNV.Dapr.FeatureManagement --version 2.1.0-preview.1756698443
NuGet\Install-Package DNV.Dapr.FeatureManagement -Version 2.1.0-preview.1756698443
<PackageReference Include="DNV.Dapr.FeatureManagement" Version="2.1.0-preview.1756698443" />
<PackageVersion Include="DNV.Dapr.FeatureManagement" Version="2.1.0-preview.1756698443" />
<PackageReference Include="DNV.Dapr.FeatureManagement" />
paket add DNV.Dapr.FeatureManagement --version 2.1.0-preview.1756698443
#r "nuget: DNV.Dapr.FeatureManagement, 2.1.0-preview.1756698443"
#:package DNV.Dapr.FeatureManagement@2.1.0-preview.1756698443
#addin nuget:?package=DNV.Dapr.FeatureManagement&version=2.1.0-preview.1756698443&prerelease
#tool nuget:?package=DNV.Dapr.FeatureManagement&version=2.1.0-preview.1756698443&prerelease
DNV.Dapr.FeatureManagement
A powerful feature management library that integrates Microsoft Feature Management with Dapr Configuration components, providing distributed feature flag capabilities with caching support.
Overview
This library extends Microsoft's Feature Management framework to work seamlessly with Dapr Configuration components, enabling distributed feature flag management across microservices architectures. It provides automatic caching, fallback mechanisms, and easy integration with ASP.NET Core applications.
Features
- ✅ Dapr Configuration Integration: Use Dapr Configuration components as feature flag store
- ✅ Distributed Caching: Built-in caching with configurable expiration
- ✅ Fallback Support: Graceful degradation when Dapr services are unavailable
- ✅ Easy Setup: Simple dependency injection configuration
- ✅ Configurable Key Prefix: Support for different key naming conventions (Azure App Configuration, custom formats)
- ✅ Configurable Options: Customizable component names, metadata, and cache settings
Installation
dotnet add package DNV.Dapr.FeatureManagement
Prerequisites
- .NET 8.0 or later
- Dapr runtime
- Dapr Configuration component configured
Quick Start
1. Configure Dapr Configuration Component
Create a Dapr Configuration component (e.g., configuration.yaml
):
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: configuration
spec:
type: configuration.redis
version: v1
metadata:
- name: redisHost
value: "localhost:6379"
2. Register Services
using DNV.Dapr.FeatureManagement;
var builder = WebApplication.CreateBuilder(args);
// Option 1: Using configuration section
builder.Services.AddDaprFeatureManagement(
builder.Configuration.GetSection("DaprFeatureFilter")
);
// Option 2: Using configuration action
builder.Services.AddDaprFeatureManagement(options =>
{
options.ComponentName = "configuration";
options.DefaultValue = false;
options.KeyPrefix = ".appconfig.featureflag/";
options.ExpirationToNow = TimeSpan.FromMinutes(5);
});
builder.Services.AddDapr();
var app = builder.Build();
3. Configure Feature Flags
Add feature flags to your appsettings.json
:
{
"FeatureManagement": {
"NewUserInterface": false,
"AdvancedSearch": true,
"BetaFeatures": false
},
"DaprFeatureFilter": {
"ComponentName": "configuration",
"DefaultValue": false,
"ExpirationToNow": "00:01:00"
}
}
4. Use Feature Flags
In Controllers
[ApiController]
[Route("[controller]")]
public class HomeController : ControllerBase
{
private readonly IFeatureManager _featureManager;
public HomeController(IFeatureManager featureManager)
{
_featureManager = featureManager;
}
[HttpGet]
public async Task<IActionResult> Get()
{
if (await _featureManager.IsEnabledAsync("NewUserInterface"))
{
return Ok("New UI is enabled!");
}
return Ok("Standard UI");
}
}
In Services
public class UserService
{
private readonly IFeatureManager _featureManager;
public UserService(IFeatureManager featureManager)
{
_featureManager = featureManager;
}
public async Task<List<User>> GetUsersAsync()
{
var users = await GetBasicUsersAsync();
if (await _featureManager.IsEnabledAsync("AdvancedSearch"))
{
// Add advanced search capabilities
users = await EnhanceWithAdvancedSearch(users);
}
return users;
}
}
Configuration Options
DaprFeatureFilterOptions
Property | Type | Default | Description |
---|---|---|---|
ComponentName |
string | "configuration" | Name of the Dapr configuration component |
DefaultValue |
bool | false | Default value when feature flag is not found |
Metadata |
Dictionary<string, string> | Empty | Additional metadata for Dapr configuration requests |
KeyPrefix |
string | "" | Prefix for feature flag keys (e.g., ".appconfig.featureflag/" for Azure App Configuration) |
ExpirationToNow |
TimeSpan | 30 seconds | Cache expiration time |
Example Configuration
{
"DaprFeatureFilter": {
"ComponentName": "my-config-store",
"DefaultValue": false,
"KeyPrefix": "ff/",
"ExpirationToNow": "00:00:10"
}
}
Feature Flag Format
The library supports flexible key prefixes for different configuration stores. For Azure App Configuration, use the following format:
{
"ff/NewUserInterface": {
"id": "NewUserInterface",
"description": "Enable the new user interface",
"enabled": true
}
}
For custom configuration stores, you can configure the key prefix:
// For custom prefix
builder.Services.AddDaprFeatureManagement(o =>
{
o.ComponentName = "my-config-store";
o.KeyPrefix = "ff/";
});
Which would expect keys like:
{
"features/NewUserInterface": {
"id": "NewUserInterface",
"description": "Enable the new user interface",
"enabled": true
}
}
Architecture
Components
- DaprFeatureFilter: The core feature filter that evaluates feature flags using Dapr Configuration
- DaprFeatureDefinitionProvider: Provides feature definitions from configuration
- DaprFeatureFilterOptions: Configuration options for the filter
- FeatureFlag: Model representing a feature flag
Flow
- Feature flag evaluation request
- Check local configuration first
- Check distributed cache
- Query Dapr Configuration component
- Cache result and return value
- Fallback to default value on errors
Best Practices
1. Use Meaningful Names
// Good
"EnableAdvancedAnalytics"
"ShowPremiumFeatures"
"UseNewPaymentGateway"
// Avoid
"Feature1"
"NewStuff"
"Test"
2. Set Appropriate Cache Duration
// For frequently changing flags
options.ExpirationToNow = TimeSpan.FromSeconds(30);
// For stable flags
options.ExpirationToNow = TimeSpan.FromMinutes(10);
3. Handle Failures Gracefully
public async Task<IActionResult> GetData()
{
try
{
var useNewApi = await _featureManager.IsEnabledAsync("UseNewAPI");
return useNewApi ? await GetDataFromNewApi() : await GetDataFromLegacyApi();
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Feature flag evaluation failed, using default behavior");
return await GetDataFromLegacyApi();
}
}
4. Use Dependency Injection
// Register as singleton for better performance
builder.Services.AddSingleton<IMyService, MyService>();
Troubleshooting
Common Issues
1. Feature flags not updating
Problem: Changes to feature flags in Dapr Configuration are not reflected immediately.
Solution: Check cache expiration settings and ensure the Dapr Configuration component is properly configured.
// Reduce cache time for testing
options.ExpirationToNow = TimeSpan.FromSeconds(1);
2. Dapr Configuration component not found
Problem: DaprException
when trying to access configuration.
Solution: Verify the component name and ensure Dapr sidecar is running.
options.ComponentName = "your-actual-component-name";
3. Default values always returned
Problem: Feature flags always return the default value.
Solution: Check the feature flag key format and ensure it matches the expected pattern with the correct prefix.
{
".appconfig.featureflag/YourFeatureName": {
"enabled": true
}
}
Or for custom prefixes:
// Configure the key prefix to match your store
options.KeyPrefix = "myapp/features/";
Performance Considerations
- Caching: The library uses distributed caching to minimize calls to Dapr Configuration
- Async Operations: All operations are asynchronous to prevent blocking
- Error Handling: Graceful degradation ensures application stability
- Memory Usage: Configurable cache expiration prevents memory leaks
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Related Projects
Support
For issues and questions:
- Create an issue in the repository
- Contact the development team
- Check the troubleshooting section above
Author: Eric Liu li.eric.liu@dnv.com
Target Framework: .NET 8.0
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net8.0
- Dapr.AspNetCore (>= 1.15.4)
- Microsoft.FeatureManagement (>= 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.0-preview.1756698443 | 122 | 9/1/2025 |