DEV Community

AvlCodeMonkey for AvlCodeMonkey Industries

Posted on Originally published at featureflags.app on

Using Microsoft FeatureManagement Without Azure App Configuration

Search for Microsoft.FeatureManagement and a lot of tutorials eventually lead to Azure App Configuration.

Nothing wrong with Azure. It's a perfectly good service. But here's the thing: Microsoft.FeatureManagement doesn't actually require it.

The library doesn't care where your feature flags come from. It reads definitions through an abstraction, and you get to decide what's behind it.

Let's look at a few options.

Option 1: appsettings.json (or any configuration source)

The simplest approach is to use IConfiguration, which is what AddFeatureManagement() uses by default.

builder.Services.AddFeatureManagement();
Enter fullscreen mode Exit fullscreen mode

And in appsettings.json:

{
  "FeatureManagement": {
    "NewDashboard": true
  }
}
Enter fullscreen mode Exit fullscreen mode

You can also use environment variables, user secrets, or any other configuration provider supported by .NET.

The good:

  • No additional dependencies.
  • Configuration lives alongside the application.
  • Easy to understand and maintain.

The not-so-good:

  • Changing a flag may mean changing configuration on every server.
  • Depending on your deployment setup, that can mean a deployment.
  • No management dashboard.
  • No audit trail beyond whatever you get from source control.

For a handful of flags that only change when you deploy, this is probably all you need. Don't build a spaceship to cross the street.

Option 2: Roll your own IFeatureDefinitionProvider

Want more control? You can provide your own implementation of IFeatureDefinitionProvider.

That means feature definitions can come from a database, an API, or whatever storage mechanism makes sense for your application.

For example:

public class DatabaseFeatureDefinitionProvider(IFlagStore store)
    : IFeatureDefinitionProvider
{
    public async IAsyncEnumerable<FeatureDefinition>
        GetAllFeatureDefinitionsAsync()
    {
        foreach (var flag in await store.GetAllAsync())
            yield return ToDefinition(flag);
    }

    public async Task<FeatureDefinition> GetFeatureDefinitionAsync(
        string featureName)
    {
        var flag = await store.GetAsync(featureName);

        return flag is null
            ? new FeatureDefinition { Name = featureName }
            : ToDefinition(flag);
    }

    private static FeatureDefinition ToDefinition(Flag flag) => new()
    {
        Name = flag.Name,
        EnabledFor = flag.Enabled
            ? [new FeatureFilterConfiguration { Name = "AlwaysOn" }]
            : []
    };
}
Enter fullscreen mode Exit fullscreen mode

Register it after feature management:

builder.Services.AddFeatureManagement();

builder.Services.AddSingleton<
    IFeatureDefinitionProvider,
    DatabaseFeatureDefinitionProvider>();
Enter fullscreen mode Exit fullscreen mode

Now you're in charge.

Which is both the good news and the bad news.

You own the storage, caching, invalidation, management UI, audit trail, and access control. Congratulations, you've just given yourself a few more things to maintain.

Option 3: Use a hosted service

This is essentially option 2, except someone else has already built the provider, dashboard, and caching.

A hosted feature flag service can refresh definitions in the background and keep an in-memory copy. That means feature checks don't need to wait for a network call.

For example, with the FeatureFlags.app client:

using Acmi.FeatureFlags.Client;

builder.AddFeatureFlags();
Enter fullscreen mode Exit fullscreen mode

Your existing IFeatureManager, [FeatureGate], and <feature> usage stays the same.

The trade-offs are worth understanding:

  • You're adding another service and dependency.
  • Pricing may increase as your flag count grows.
  • Changes arrive on a refresh interval (15 minutes by default), rather than instantly.
  • If the service is unreachable when the app starts, flags remain off until the first successful fetch.

It's a reasonable middle ground when you want a dashboard and runtime changes without building and maintaining the whole thing yourself.

Where does Azure App Configuration fit?

Azure App Configuration is another hosted option, and a particularly good fit if you're already running in Azure.

You get configuration settings, Key Vault references, and feature flags in one place. If you're using managed identities and the rest of the Azure ecosystem, it can be a natural choice.

The trade-off is that you're taking on an Azure service and managing your flags through its portal.

So, which one should you use?

It depends on what problem you're actually trying to solve.

  • A few flags that change with deployments? Use appsettings.json. Keep it simple.
  • A custom workflow or specialized storage requirements? Implement IFeatureDefinitionProvider. Just be prepared to own the plumbing.
  • A dashboard and runtime changes without building your own infrastructure? Consider a hosted service.
  • Already invested in Azure? Azure App Configuration may be the obvious choice.

The important bit is that your feature-checking code doesn't need to change between these approaches. You can start with configuration files and move to a different provider as your needs evolve.

No need to marry your feature flags to your configuration backend.

And if you'd rather spend your time building features instead of building a feature flag management system, FeatureFlags.app is another option worth a look. It's a hosted dashboard for Microsoft.FeatureManagement, without requiring Azure App Configuration.

Choose the tool that fits the problem. Your future maintenance schedule will thank you.

Top comments (0)