Feature Toggles in ASP.NET Core
Because we want to keep work items as small as possible, it's not always possible to deliver value when you're using CI/CD, simply because a feature is just not done yet. Yes, you did finish the story and yes you added value. But it's simply not good enough for production yet. More and more stories are completed and merged to the main branch, now what do you do? Release a partially finished feature along with the bug fixes, or wait for the entire feature to complete before you release. The real answer is feature toggles. And once you worked with them, you'll probably never go back.

I think this is a very common real-world development problem. You’re working as a team but not everyone on the team is working on the same story. There are two features actively worked on. Feature A and Feature B. Feature A is a complex one, it contains a lot of stories and tasks to complete. Feature B is relatively easy as it’s complexity is way less. Now the first story of Feature A is complete and ready for review. So a pull request is created and in the end, the story is merged to the main branch. Your team has a full-blown CI/CD pipeline in place, so a build is kicked off and the completed story is deployed to a test environment ready to be tested. But since Feature A contains a huge amount of stories, Feature A is not even near complete. So you will never promote this pipeline to production. In the meanwhile, your teammates finished Feature B and merged it to main which (again) also starting the pipeline. Feature B is really important and adds a lot of value for your customer. Now, what do you do? Bring it to production, including a half complete Feature A, or do you wait for Feature A to complete?

Feature toggles

The answer can be found in Feature Management. You can use a NuGet package called Microsoft.FeatureManagement which helps you creating feature toggles. This allows you to add some lines to your system’s configuration in which you switch certain features on or off. So in the example above, you do want Feature A to be available on your test environment, simply because you want your testers to start working with stories as soon as they are done. But you don’t want this feature to be available in production, simply because it’s not even near complete.

Configuration

It starts with configuration, and luckily you can manipulate these configurations using ARM Templates. This allows you to configure features per environment independently. So in this case, you want to be able to enable or disable Feature A.

    "FeatureManagement:FeatureA": true

Now for Feature B, it doesn’t make sense to create a feature toggle (or feature flag if you like). This feature must be available in all environments as soon as possible.

Add feature toggles

Now add the feature management package Microsoft.FeatureManagement to your project.

dotnet add package Microsoft.FeatureManagement

In your ASP.NET project, find the Startup.cs class and add FeatureManagement to the services:

services.AddFeatureManagement();

Feature management is now configured and running on your API.

Implementing toggles

Now when you’re running your API, Azure Functions or a business library somewhere, you can inject the IFeatureManager and see if features are toggled on or off:

var featureIsEnabled = await _featureManager.IsEnabledAsync("FeatureA");

Also, you can use an attribute on your controller to allow execution only if the feature is enabled:

// Or the entire controller
[FeatureGate("FeatureA")]
public class HomeController : Controller
{
    // ...
}

// Or on an individual action of a controller
[FeatureGate("FeatureA")]
public IActionResult Index()
{
    return View();
}

You can even specify a time window for which a feature must be enabled. You could use this for example to theme your website for Christmas.

"FeatureA": {
    "EnabledFor": [
        {
            "Name": "Microsoft.TimeWindow",
            "Parameters": {
                "Start": "2020/12/10 00:00:00 GMT",
                "End": "2021/01/03 00:00:00 GMT"
            }
        }
    ]
}

Conclusion

These feature toggles are pretty nifty. I think the downside is that you need to change your source code and make sure your software is backward compatible if a feature is turned off. Also, once a feature is fully implemented you may need another user story to remove the feature flag and enable the thing by default. I’m using magic strings in the above example, but if you use a constant or something similar, removing the feature flag is easier.

Anyways, feature toggles and especially with Microsoft FeatureManagement will make your life as a team member of a development team a lot easier!


Last modified on 2020-06-17

Hi, my name is Eduard Keilholz. I'm a Microsoft developer working at 4DotNet in The Netherlands. I like to speak at conferences about all and nothing, mostly Azure (or other cloud) related topics.