Press ESC to close

Using Feature Flags in .Net 6

Topics covered in this article are…

  1. What are Feature Flags?
  2. Setting up Feature Flags
  3. Defining Feature Flags
  4. Using IFeatureManager with Dependency Injection
  5. Defining Constant
  6. Way to check Feature Flags
  7. Conclusion

What are Feature Flags?

Feature flags, also known as feature toggles or feature switches, are a technique used in software development to control the availability of specific features within an application. They allow developers to turn certain features on or off without changing the codebase. With feature flags, developers can introduce new features gradually, test them in a real environment, and decide whether to make them accessible to all users or limit them to a specific group. This approach provides more flexibility and reduces the risk of deploying new features that might have unexpected bugs or impact the user experience negatively.

In simple terms, feature flags give developers the power to manage and control features in their software, enabling them to safely experiment and roll out changes at their own pace.

Setting up Feature Flags:

Creating New Project:
Please follow this link to learn how to create a new project:

https://learn.microsoft.com/en-us/visualstudio/ide/create-new-project?view=vs-2022

Install NuGet Package:
First, you need to add Microsoft.FeatureManagement.AspNetCore NuGet package to your .NET 6 project. This package provides the necessary functionality for working with feature flags.

Configuration Setup:
The .NET feature manager seamlessly integrates with the framework’s built-in configuration system, allowing you to define your application’s feature flag settings using various configuration sources supported. NET. Examples of these sources include the local appsettings.json file or environment variables. With this flexibility, you can easily customize and manage feature flags based on different configuration options, making it convenient to control your application’s behavior without changing the codebase.

Modify Program.cs:
Open the Program.cs file in your project. Inside the ConfigureServices method, call the AddFeatureManagement method on the IServiceCollection.

using Microsoft.FeatureManagement;

builder.Services.AddFeatureManagement();

To configure feature management to use a specific section in your configuration, you can use the method Configuration.GetSection and provide the name of the desired section. The following example tells the feature manager to read from a different section called “FeatureManagement” instead:

using Microsoft.FeatureManagement;

var configuration = new ConfigurationBuilder()
   .AddJsonFile("appsettings.json")
   .Build()
   .GetSection("FeatureManagement");
​​

///   or
​
builder.Services
   .AddFeatureManagement(builder.Configuration.GetSection("FeatureManagement"));

Use Filters in your Feature Flags:
If you want to use filters in your feature flags, follow these steps:
a) Include the Microsoft.FeatureManagement.FeatureFilters namespace.
b) Add a call to AddFeatureFilter and specify the type name of the desired filter as the generic type of the method.

The following example shows how to use a built-in feature filter called PercentageFilter:

using Microsoft.FeatureManagement;

builder.Services.AddFeatureManagement()
   .AddFeatureFilter<PercentageFilter>();

Defining Feature Flags:

A feature flag declaration consists of two parts: a name and a list of filters. These filters are used to decide if a feature should be turned on (when it’s active or “True”). Each filter sets a condition for when the feature should be enabled.

If a feature flag has multiple filters, they are checked one by one. When a filter determines that the feature should be enabled, the process stops, and the feature is turned on. Any remaining filters are skipped. If no filter says the feature should be enabled, it remains off.

The feature manager uses an appsettings.json file to store feature flag settings. Here’s an example of how you can set up feature flags in a JSON file:

{"FeatureManagement": {
       "FirstFeature": true, // Feature flag set to on
       "SecondFeature": false, // Feature flag set to off
       "ThirdFeature": {
           "EnabledFor": [
               {
                   "Name": "Percentage",
                   "Parameters": {
                       "Value": 50
                   }
               }
           ]
       }
   }
}
In this example, we have three feature flags with their respective filters defined in the EnabledFor property:

  1. FirstFeature is on.
  2. SecondFeature is off.
  3. ThirdFeature specifies a filter named Percentage with a Parameters property. This filter is configurable and sets a 50-percent probability for the ThirdFeature flag to be on. For a detailed guide on using feature filters, you can check out “Use feature filters to enable conditional feature flags.”

Using IFeatureManager With Dependency Injection:

To perform certain operations, like manually checking feature flag values, you need to use something called the IFeatureManager. In ASP.NET Core MVC, you can access the IFeatureManager through dependency injection.

Here’s how you can do it:
  1. Add an argument of type IFeatureManager to the constructor of your controller.
  2. The runtime will automatically provide an implementation of IFeatureManager when calling the constructor.
using Microsoft.FeatureManagement;

public class MyController : Controller
{
   private readonly IFeatureManager _featureManager;
   public MyController(IFeatureManager featureManager)
   {
       _featureManager = featureManager;
   }
}

Defining Constant:

Define feature flags as string variables to reference them from code:

public static class MyFeatureFlags
{
   public const string FirstFeature = "FirstFeature";
   public const string SecondFeature = "SecondFeature";
   public const string ThirdFeature = "ThirdFeature";
}

Way to Check Feature Flags:

Declaring feature flags in ASP.NET Core can be achieved in both traditional Controller-based and the newer Minimal APIs. I’ll provide examples for both approaches:

1) Controller-Based:

In a traditional MVC (Model-View-Controller) application, you can implement feature flags to control the visibility of specific features or sections of your application based on configuration settings. This approach allows you to enable or disable features without redeploying the application, making it useful for A/B testing, phased rollouts, and continuous delivery.

  • In C# code
A common pattern in feature management is to check if a feature flag is enabled and if so, execute a section of code. For example
public MyController(IFeatureManager featureManager)
       {
           _featureManager = featureManager;
       }

        public async Task<IActionResult> Index()
       {
           if (await _featureManager.IsEnabledAsync(MyFeatureFlags.FirstFeature))
           {
               return View();
           }
           return RedirectToAction("Error");
       }​

       [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
       public IActionResult Error()
       {
           return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
       }
   }

  • In Controller Action
In MVC controllers, you can use the “FeatureGate” attribute to control whether a whole controller class or a specific action is enabled. Let’s see some examples:

     a) Controlling the Whole Controller Class:
using Microsoft.FeatureManagement.Mvc;

[FeatureGate(MyFeatureFlags.FirstFeature)]
public class MyController : Controller
{
   // Actions in this controller require FirstFeature to be enabled to run
   // If FirstFeature is off, the actions will be blocked
   // You can define multiple actions in this controller
   // All actions will follow the same FirstFeature condition.
}

     b) Controlling Specific Actions: 
using Microsoft.FeatureManagement.Mvc;
public class MyController : Controller
{
   // This action requires FirstFeature to be enabled to run
   // If FirstFeature is off, this action will be blocked
   [FeatureGate(MyFeatureFlags.FirstFeature)]
   public IActionResult Index()
   {
       return View();
   }

   // Other actions in this controller...
}

Note: When a controller or action is blocked because the controlling feature flag is off, a special interface called “IDisabledFeaturesHandler” is called. By default, it returns a 404 status code to the client with no response body.

In simple terms, using the “FeatureGate” attribute, you can easily control which parts of your application (controllers or actions) should be active based on the state of specific feature flags. If a feature flag is off, the corresponding actions will be blocked, and you can handle that situation using the “IDisabledFeaturesHandler” interface.

  • In MVC View
To use feature flags in MVC views, follow these steps:

  1. Open the _ViewImports.cshtml file located in the “Views” directory.
  2. Add the feature manager tag helper to this file:
@addTagHelper *, Microsoft.FeatureManagement.AspNetCore
  1. Now you can use the <feature> tag in your views to show content based on whether a feature flag is enabled:
Example 1: Show content if ‘FirstFeature’ is enabled.
<feature name="FirstFeature">
   <p>This can only be seen if 'FirstFeature' is enabled.</p>
</feature>
Example 2: Show alternate content if ‘FirstFeature’ is disabled.
<feature name="FirstFeature" negate="true">

   <p>This will be shown if 'FirstFeature' is disabled.</p>

</feature>
Example 3: Show content if both ‘FirstFeature’ and ‘SecondFeature’ are enabled.
<feature name="FirstFeature, SecondFeature" requirement="All">
   <p>This can only be seen if 'FirstFeature' and 'SecondFeature' are enabled.</p>

</feature>
Example 4: Show content if either ‘FirstFeature’, ‘SecondFeature’, or both are enabled.
<feature name="FirstFeature, SecondFeature" requirement="Any">
   <p>This can be seen if 'FirstFeature', 'SecondFeature', or both are enabled.</p>
</feature>
Note: Using the <feature> tag in your views allows you to easily control what content is displayed based on the state of feature flags, providing a way to enable or disable specific parts of your views without changing the underlying code.

  • In MVC Filter
To control when an MVC filter should be active based on a feature flag, you can set up a filter that implements IAsyncActionFilter. Let’s see how you can do this:

Step 1: Define the Feature Flag:
Make sure you have defined the feature flag MyFeatureFlags.FirstFeature in your feature management configuration.

Step 2: Set up the MVC Filter:
In your Program.cs or where you configure services, add the following code to set up the filter:
using Microsoft.FeatureManagement.FeatureFilters;

public void ConfigureServices(IServiceCollection services)
{
   services.AddMvc(options => {

       // Add ThirdPartyActionFilter as an MVC filter for the feature flag FirstFeature

       options.Filters.AddForFeature<ThirdPartyActionFilter>(MyFeatureFlags.FirstFeature);
   });
}
In this example, we added ThirdPartyActionFilter as an MVC filter, and it will be triggered within the MVC pipeline only if the feature flag FirstFeature is enabled.

Step 3: Use the Feature Flag Filter:
Now, the ThirdPartyActionFilter will run as part of the MVC pipeline only when the feature flag FirstFeature is enabled. This allows you to apply specific behavior or actions in the filter based on the state of the feature flag.

By setting up filters with feature flags, you can easily control when specific filters should be active based on the state of feature flags in your application. This way, you can enable or disable certain filter behavior without modifying the underlying filter code.

  • In Middleware
You can use feature flags to add application branches and middleware conditionally. Let’s see how:

1. Conditionally Insert Middleware:
In the following code, a middleware component named ThirdPartyMiddleware is inserted into the request pipeline only when the feature flag FirstFeature is enabled:

app.UseMiddlewareForFeature<ThirdPartyMiddleware>(MyFeatureFlags.FirstFeature);

2. Branch the Entire Application:
You can also use feature flags to branch the entire application based on a feature flag. The code below allows you to add middleware (T) to the application pipeline based on the status of a feature flag (featureName):
app.UseForFeature(featureName, appBuilder => {
   appBuilder.UseMiddleware<T>();
});
By using feature flags in this way, you can dynamically adjust your application’s behavior based on the state of the feature flags. This gives you the flexibility to activate or deactivate middleware components without changing the core application code.

2) Minimal API:

With Minimal APIs in .NET 6, you can achieve the same functionality with a more concise code style. Here’s how you can declare feature flags using Minimal API:

Here, we are creating a straightforward minimal API project that utilizes feature flags in conjunction with the PercentageFilter. The feature flags enable us to dynamically control the availability of certain features in the application, while the PercentageFilter allows us to selectively enable these features for a specific percentage of incoming requests. This approach provides us with the flexibility to perform A/B testing or gradual rollouts of new functionality in the application.

Step 1: First, create a Feature Flag Endpoint.cs class

public class FeatureFlagEndpoint : IEndpointFilter
{
   public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
   {

       var endpoint = context.HttpContext.GetEndpoint();

       var methodName = string.Empty;

       if (endpoint != null)
       {

           // Access endpoint metadata or other information as needed


           if (endpoint.Metadata.GetMetadata<EndpointNameMetadata>() is { } nameMetadata)

           {
               methodName = nameMetadata.EndpointName;

           }

       }

       var featureFlag = context.HttpContext.RequestServices.GetRequiredService<IFeatureManager>();

       var isEnabled = await featureFlag.IsEnabledAsync($"Api_{methodName}");

       if (!isEnabled)

       {
           return Results.NotFound();
       }
       return await next(context);
   }

}
  • in above code, implementation of the FeatureFlagEndpoint class, which is an IEndpointFilter used in a Minimal API with Microsoft Feature Management.
  • The FeatureFlagEndpoint class implements the IEndpointFilter interface, which means it needs to provide an InvokeAsync method. In the InvokeAsync method, the endpoint being accessed is retrieved from the EndpointFilterInvocationContext using context.HttpContext.GetEndpoint()
  • The feature flag’s state is obtained using await featureFlag.IsEnabledAsync(featureFlagName), and if the feature is not enabled (isEnabled is false), the code returns a Results.NotFound() result. This effectively prevents access to the endpoint, and a 404 response will be returned.
  • If the feature is enabled, the next(context) is called, which allows the request to proceed through the pipeline and reach the endpoint’s handler.
  • FeatureFlagEndpoint class acts as a filter for API endpoints, allowing or denying access based on the state of the corresponding feature flag. If the feature flag is disabled for a specific endpoint, the endpoint will not be accessible, and a 404 response will be returned. Otherwise, the request will be allowed to proceed to the endpoint’s handler.
Step 2: Configure Feature Flags in Program.cs:

using FeatureFlagsWithMinimulAPI_Demo;
using Microsoft.FeatureManagement;
using Microsoft.FeatureManagement.FeatureFilters;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container

builder.Services.AddEndpointsApiExplorer();

builder.Services.AddFeatureManagement()
   .AddFeatureFilter<PercentageFilter>();

var app = builder.Build();

app.MapGet("/newweatherforecast", () =>
{
   var forecast = Enumerable.Range(1, 10).Select(index =>
       new WeatherForecastNew
       (
           DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
           Random.Shared.Next(-20, 55)
       ))
       .ToArray();
   return forecast;
})

.AddEndpointFilter<FeatureFlagEndpoint>()
.WithName("NewGetWeatherForecast")
.WithOpenApi();

app.Run();

// create WeatherForecastNew object
public class WeatherForecastNew
{
   public DateOnly Date { get; set; }
   public int TemperatureC { get; set; }
   public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

   public WeatherForecastNew(DateOnly date, int temperatureC)
   {
       Date = date;
       TemperatureC = temperatureC;
   }
}

  • in this above code, Feature Management services are added to the services collection, and the PercentageFilter is registered using builder.Services.AddFeatureManagement().AddFeatureFilter<PercentageFilter>().
  • create API defines an GET endpoint at the path “/newweatherforecast”. When accessed, it returns an array of WeatherForecastNew objects. The WeatherForecastNew the class represents a weather forecast with properties for date and temperature in Celsius and Fahrenheit.
  • Feature flags are applied to the endpoint using app.MapGet().AddEndpointFilter<FeatureFlagEndpoint>(). The FeatureFlagEndpoint class is a custom feature filter that enables or disables this endpoint based on the feature flag’s configuration.
  • The feature flag is named “NewGetWeatherForecast” and is defined in the Microsoft Feature Management configuration. By using .WithName(“NewGetWeatherForecast”), the feature flag is associated with this endpoint.

Step 3: Configure the feature flag in appsettings.json:
"FeatureManagement": {
   "Api_NewGetWeatherForecast": {
     "EnabledFor": [
       {
         "Name": "Percentage",
         "Parameters": {
           "Value": 50
        }
      }
    ]
  }
}
  • “Api_NewGetWeatherForecast”: The name of the feature flag. This name should match the feature flag associated with the endpoint in the code.
  • “EnabledFor”: This array contains a single element, which specifies the filter used to enable the feature flag.
  • “Name”: “Percentage”: Specifies that the feature flag should be enabled using the PercentageFilter.
  • “Parameters”: { “Value”: 50 }: The PercentageFilter requires a parameter called “Value”, which represents the percentage of requests for which the feature should be enabled. In this case, the feature “Api_NewGetWeatherForecast” is enabled for 50% of the requests.
In this configuration, the “Api_NewGetWeatherForecast” feature flag will be enabled for approximately 50% of the requests, and it will be disabled for the other 50% of requests. This allows you to gradually roll out the feature to a portion of your users or control its behavior based on different usage scenarios.

Conclusion:

In conclusion, feature flags are a powerful technique that enables developers to control the behavior of their applications without making code changes or redeploying. By using feature flags, you can toggle features on or off for different users or environments, allowing for more flexible and gradual feature rollouts. This helps improve development speed, reduces risks, and empowers you to make data-driven decisions based on user feedback and usage patterns.

Feature flags also provide a great way to conduct A/B testing, segment users, and manage feature toggles dynamically. They allow you to experiment with new functionalities and gather real-time insights before fully releasing them to all users.

Overall, feature flags are a valuable tool for modern software development, offering a safer and more agile approach to deploying and managing features in your applications.

Do You Need more information?

For any further information / query regarding Technology, please email us at info@varianceinfotech.in
OR call us on +1 630 534 0223 / +91-7016851729, Alternately you can request for information by filling up Contact Us

Chirag Darji

Chirag is a Business strategist, helping Variance Infotech to spread their expertise in Dotnet development & CRM solutions for all industries among businesses which has been proven a Boost-up factor in the digital aura worldwide.

Leave a Reply

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

Subscribe to our newsletter

Please wait...
Want to be notified when our article is published? Enter your email address and name below to be the first to know.