Feature Flag Your .NET Applications

I’ve written about feature flagging your applications in the past. We’ve looked at services like LaunchDarkly and Microsoft Azure’s App Configuration service – full featured services that you can subscribe to, that brings about a lot of exciting features to selectively and safely light up new features in your applications. But if you don’t want to integrate with those third-party services, you can try out Microsoft’s Feature Management package. It’s free and doesn’t require any integration with any third-party services. In today’s post, let’s dig into how we can wire this up and use it.

Install and Configure

To set this up, download and install the Microsoft.FeatureManagement NuGet package.

dotnet add package Microsoft.FeatureManagement

I’ll be using this within the context of an ASP.NET application and as such, I’ll install the package that provides additional support for such applications.

dotnet add package Microsoft.FeatureManagement.AspNetCore

Once the package is installed, you can register it in your DI container like so:

using Microsoft.FeatureManagement;
...
services.AddFeatureManagement();

Define Your Feature Flags

This feature management system works on the IConfiguration interface. In other words, you can add your feature flags in any of the configuration providers supported by dotnet – appsettings.json files, environment variables, secrets.json, ini files, or even your own custom implementation of IConfiguration – and then interact with those flags in your code using this FeatureManagement library.

For demonstration purposes, let’s go define a feature flag in our appsettings.json file.

{
  "MySuperAwesomeFeature":  false
}

A feature flag, at its most elemental level is a Boolean, a true or false. A toggle. An on/off switch. Above, I’m defining such a flag, named MySuperAwesomeFeature. The value is current set to false, meaning that this feature should currently be disabled in the application.

Toggle an API Endpoint

Now, let’s start adding feature toggling logic within our code. Say you have a .NET web API and you want to control the availability of a particular endpoint using FeatureManagement. To do so, you can decorate your endpoint with a FeatureGate attribute.

using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;

namespace FeatureManagementExplorations.Controllers;

[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<TestController> _logger;

    public TestController(ILogger<TestController> logger)
    {
        _logger = logger;
    }

    [HttpGet("weather")]
    public IEnumerable<WeatherForecast> GetWeather()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
        .ToArray();
    }

    [FeatureGate("MySuperAwesomeFeature")]
    [HttpGet("awesome")]
    public string GetAwesomeness()
    {
        return "You're awesome";
    }
}

In the Controller above, I’ve decorated the /awesome endpoint with the FeatureGate attribute. This attribute takes one or more flags that FeatureManagement will evaluate in sequence to determine whether or not traffic should be passed through to the respective action method. With the MySuperAwesomeFeature flag set to false, run your application and navigate to this endpoint.

an invocation of the awesome endpoint resulting in a 404 as this endpoint is covered in a feature flag that is currently set to false

You’ll notice that ASP.NET returns a 404 (Not Found) error. That is because this feature is currently set to off (false). Let’s go to our appsettings.json and change the value to true and re-run this request.

With the feature flag enabled, the endpoint returns a successful response.

Other Usage

Feature flagging ability is not restricted to simply allowing and denying access to endpoints using this attribute. You can do all sorts of control flow logic within your application using this. Consider the modified version of the TestController and its /awesome action method, below.

using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement;

namespace FeatureManagementExplorations.Controllers;

[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
    private readonly IFeatureManager feature;

    public TestController(IFeatureManager feature)
    {
        this.feature = feature;
    }

    [HttpGet("awesome")]
    public async Task<string> GetAwesomeness()
    {
        if (await feature.IsEnabledAsync("MySuperAwesomeFeature"))
        {
            return "You're awesome!";
        }
        else
        {
            return "You're great!";
        }
    }
}

Here, we’re instantiating an instance of FeatureManager via constructor injection. Since we have FeatureManagement registered in our Dependency Injection (DI) container, we can ask it to give us an instance of it by asking for IFeatureManager within our constructor. With that in place, we can check the current value of a feature flag by using the IsEnabledAsync method.

Conclusion

We’ve covered the basics but this library is pretty robust with other features such as Feature Filters, Time Window, Targeting and others so be sure to check out the GitHub repository for additional examples and further study.

Leave a Comment

Your email address will not be published. Required fields are marked *