DNV.Dapr.FeatureManagement 2.1.0-preview.1756698443

This is a prerelease version of DNV.Dapr.FeatureManagement.
dotnet add package DNV.Dapr.FeatureManagement --version 2.1.0-preview.1756698443
                    
NuGet\Install-Package DNV.Dapr.FeatureManagement -Version 2.1.0-preview.1756698443
                    
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="DNV.Dapr.FeatureManagement" Version="2.1.0-preview.1756698443" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DNV.Dapr.FeatureManagement" Version="2.1.0-preview.1756698443" />
                    
Directory.Packages.props
<PackageReference Include="DNV.Dapr.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 DNV.Dapr.FeatureManagement --version 2.1.0-preview.1756698443
                    
#r "nuget: DNV.Dapr.FeatureManagement, 2.1.0-preview.1756698443"
                    
#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 DNV.Dapr.FeatureManagement@2.1.0-preview.1756698443
                    
#: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=DNV.Dapr.FeatureManagement&version=2.1.0-preview.1756698443&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=DNV.Dapr.FeatureManagement&version=2.1.0-preview.1756698443&prerelease
                    
Install as a Cake Tool

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

  1. DaprFeatureFilter: The core feature filter that evaluates feature flags using Dapr Configuration
  2. DaprFeatureDefinitionProvider: Provides feature definitions from configuration
  3. DaprFeatureFilterOptions: Configuration options for the filter
  4. FeatureFlag: Model representing a feature flag

Flow

  1. Feature flag evaluation request
  2. Check local configuration first
  3. Check distributed cache
  4. Query Dapr Configuration component
  5. Cache result and return value
  6. 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

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

License

This project is licensed under the MIT License - see the LICENSE file for details.

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 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. 
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.0-preview.1756698443 122 9/1/2025