Explain Feature Flags in .NET Core

What are Feature Flags?

Using feature flags, a technique from software development, we can practically encapsulate our application's functionality in a conditional statement and provide a toggle to activate or deactivate the feature.

Most importantly, we can toggle features during runtime either enable or disable, meaning that we do not need to redeploy our application to enable a new feature or disable an old or broken feature.

How to Turn a Feature Flag On or Off?

  1. Boolean
  2. Time-based
  3. Percentage filter
  4. Targeting filter

A Boolean true/false feature filter is the most basic type.

Time-based filters are the next category. Only during the specified start and finish hours is the functionality active.

Utilizing a percentage feature filter is an additional choice. This means that the possibility that the feature is enabled is determined by the stated percentage.

And lastly, we have the targeting filter in ASP.NET Core. With the help of this filter, we may specify feature-enabling guidelines based on the users or groups who utilize our application. Because targeting filters are persistent, once a user has access to a feature, they will keep using it.

In the unlikely event that the built-in feature filters don't satisfy our needs, we may always design our own unique feature filters.

Benefits of Feature flags

  • Feature Flags are an effective mechanism that lets us modify our application's behavior in runtime without having to redeploy. There are numerous advantages to this.
  • Known as "dark deployments," we can introduce new features into production systems while they are disabled. This has the advantage of allowing us to make sure, before we roll out our new feature to all of our users, that it doesn't negatively impact the rest of the application.
  • Another advantage that features flags offer us is the ability to assess how effectively a new feature functions through canary deployments. To make sure there are no performance effects or other issues in the code, we can gradually increase the use of our new functionality. When we are satisfied that the feature is stable, we can then enable it for every user.
  • All things considered; feature flags help us reduce the risk associated with adding new features to our application. In the event of any performance or other problems, we can enable or stop a feature without causing any disturbances to our users.

Enabling Feature Flags in ASP.NET Core Application

Let's build an ASP.NET Core application and add some feature management to see how we may use feature flags in our applications.

Once we create the .net core application, you need to install the below-mentioned package in our application.

Microsoft.FeatureManagement.AspNetCore

The Microsoft.FeatureManagement.The AspNetCore NuGet package needs to be added first. The lifecycle of a feature flag is automatically managed by the FeatureManagement library. As a result, we can modify feature flags while the application is running without having to restart it.

Add feature flags configuration in the application.json file.

  "FeatureManagement": {
    "FeatureA": true, // Feature flag set to on
    "FeatureB": false, // Feature flag set to off
    "FeatureC": {
      "EnabledFor": [
        {
          "Name": "CustomPercentageFilter",
          "Parameters": {
            "Value": 50
          }
        }
      ]
    }
  }

Register feature management to our services side.

builder.Services.AddFeatureManagement(builder.Configuration.GetSection("FeatureManagement"))
    .AddFeatureFilter<CustomPercentageFilter>();

Where we are required to use feature management, then we need to inject the IFeatureManager interface.

Here is the resolution for the feature manager interface.

private readonly IFeatureManager _featureManager;

public FeatureMgmtController(IFeatureManager featureManager)
{
    _featureManager = featureManager;
}

We can check the added feature on the code side and, based on the code, execute it.

We can use the IsEnabledAsync method to get the result of the feature as we have configured it in the application.json.

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

It will return either true or false, so based on that, we need to execute our code.

In other words, if the return is true, then we need to execute our code; otherwise, we don't execute the code.

Here is the use of the custom filter for feature management.

We need to create the one class CustomPercentageFilter.

    [FilterAlias("CustomPercentageFilter")]
    public class CustomPercentageFilter : IFeatureFilter
    {
        public CustomPercentageFilter()
        {

        }

        public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context)
        {
            var settings = context.Parameters.Get<ValueSettings>();
            return Task.FromResult(settings.Value == 50);
        }
    }

    public class ValueSettings
    {
        public int Value { get; set; }
    }

We can check if the custom filter will be executed and it will return as either true or false.

var featureC = await _featureManager.IsEnabledAsync("FeatureC");

Here is the configuration.

"FeatureC": {
  "EnabledFor": [
    {
      "Name": "CustomPercentageFilter",
      "Parameters": {
        "Value": 50
      }
    }
  ]
}

If we set its value to 50 on the configuration side and execute the custom filter, then it will give us a true result.

If we set its value to 52 on the configuration side and execute the custom filter, then it will give us a false result because the condition is not matched. 

Here is the controller code for GET the feature result in the API response.

    [Route("api/[controller]")]
    [ApiController]
    public class FeatureMgmtController : ControllerBase
    {
        private readonly IFeatureManager _featureManager;

        public FeatureMgmtController(IFeatureManager featureManager)
        {
            _featureManager = featureManager;
        }

        [HttpGet]
        public async Task<IActionResult> GetAsync()
        {
            var featureA = await _featureManager.IsEnabledAsync("FeatureA");
            var featureB = await _featureManager.IsEnabledAsync("FeatureB");
            var featureC = await _featureManager.IsEnabledAsync("FeatureC");
            var featureNames = _featureManager.GetFeatureNamesAsync();

            return Ok(new { featureA, featureB, featureC, featureNames });
        }
    }

Let’s try to run the application and we can check the result.

Result

Here is the called our custom percentage filter evaluates our code and based on that it will give the result.

Custom percentage filter

Here is the response of the API.

API

Let’s try to set the 52 values in the custom filter and execute the API and let’s see the API response.

API response

Here is the response of the API.

Response of the API

Other Ways to Define Feature Flags

Thus far, we have defined an if-else block and used the IFeatureManager interface to verify the state of Feature Flags. Let's examine several additional approaches to verify the state of our feature flags as this is not the only one, we have.

FeatureGate Attribute

Using the FeatureGate attribute in ASP.NET Core, we may encapsulate endpoints or entire controllers in feature toggles.

[FeatureGate("FeatureA")]
[HttpGet("featurea")]
public async Task<IActionResult> GetFeatureAAsync()

Let’s try with the example so we can better understand.

Example

Feature

Here is the response of the feature gate API.

Feature gate API

Let’s set it as a false for FeatureA configuration and try to execute the FeatureA API endpoint.

FeatureA API endpoint

It will give an error with the 404 Not Found.

Although we can set it to return any value we choose, this is the default status code.

We learned the new technique and evolved together.

Happy coding!


Similar Articles