Feature Flags for ASP.Net Core Applications using Microsoft.FeatureManagement Library

Feature Flags for ASP.Net Core Applications using Microsoft.FeatureManagement Library

Feature Flags for ASP.Net Core Applications Series

In mid-2019, a team from Microsoft Azure introduced a new library called Microsoft.FeatureManagement that adds support for easily implementing Feature Flags in .Net Core applications and another NuGet package called Microsoft.FeatureManagement.AspNetCore that you can use in your Asp.Net Core applications with some added features. In this article and in the subsequent article series called Feature Flags for ASP.Net Core Applications we will investigate how to use the libraries in your applications and the capabilities it has.

Feature Flags

Feature Flags, AKA Feature toggles is a modern software development best practice that allows you to decouple a software release from a deployment. Traditionally how you would release software features is by doing a deployment into product and exposing the feature to the public depending on the deployment strategy you are using. But with feature flags, you can decouple the release from deployment and quickly change the feature availability on-demand. Allowing you do have control over when to release software features and dynamically administer the lifecycle of the feature. This article won’t dive into too many details on what are feature flags and the concepts behind it. To get a good overview of how feature management work, I can recommend Feature Management Overview documentation from Microsoft.

Why Use Microsoft.FeatureManagement Library

There are several things that are interesting about Microsoft.FeatureManagement library that we should know about. You may already have some sort of feature management built into your application that you are working on, but Microsoft.FeatureManagement library provides;

  • A common and consistent way of managing your features.
  • Built on top of IConfiguration in .Net Core, so supports all the configuration providers available for .Net core and can use JSON file for feature management if you like
  • It provides a way to manage the lifetime of a feature flag that allows feature flags to change in real-time as well as be consistent across the entire request.
  • Manage simple On/Off scenarios and complex feature scenarios with custom implementations.
  • Extensions for ASP.Net Core and MVC to tie into Razor syntax, Routing, Filter, and Action attribute, Middleware, etc.

Implementation in an ASP.Net Core Application

Let’s look at how we can implement feature flags in an ASP.Net Core MVC application. We have a sample application that we need to expose features using feature flags. Let’s look at the scenario

Music Store Application

The application is a simple implementation of a Music Store. As of now, it has 2 pages, a Home Page where some featured albums are displayed, an Albums Page where all albums available are listed with details about the albums.

Home Page

Albums Page

The development team needs to introduce 3 new features into the application hidden behind feature flags.

Promotions Page

Albums that are currently under some sort of promotion

Promotion Discount of 25%

Give 25% discount for all promotional albums

Suggested Albums on Home Page

Album suggestions for users on the home page that matches the user preference

Let’s see how we can implement the feature flags using Microsoft.FeatureManagement library for this Music Store application.

In this application, we are making use of some of the extensions provided for ASP.Net Core MVC applications. So we need to install the Microsoft.FeatureManagement.AspNetCore NuGet package.

Note: The Microsoft.FeatureManagement.AspNetCore package is in preview at the moment, so you need to Include pre-release versions in the NuGet Package Manager or include the full version number if you are installing using the dotnet CLI or command line.

Next, you need to add the feature management services into the dependency injection container. This is done in the ConfigureService() method in the Startup.cs file.

using Microsoft.FeatureManagement;

namespace MusicStore.Web
{
  public class Startup
  {
    public void ConfigureServices(IServiceCollection services)
    {
      ...
      // Configure Feature Management
      services.AddFeatureManagement();
      ...
    }
  }
}

We already know, Microsoft.FeatureManagement is built on top of IConfiguration so we can use the appsettings.json file as a start to implement our feature flags. Then later we can use any Configuration provider available for us. One excellent solution is to use the Azure App Configuration Feature Management capabilities. Let’s look at how to use that in a later article. For now, we will use appsettings.json file.

In the appsettings.json file, we need to define a FeatureManagement section. And in that section define our feature flags. We will define 3 simple feature flags according to our requirement. In our case, all we need is to enable or disable the feature. So, a simple Boolean value is enough for us. So I am defining our feature flags in the appsettings.json like this.

{
  ...
  "FeatureManagement": {
    "Promotion": false,
    "Promotion.Discounts": false,
    "Suggestion.User": false
  }
}

Currently, all features are in the disabled state. Now let’s see a few ways that we can implement the feature flags.

Toggle Access to Controllers/Controller Action Methods

To get access to the Promotions page, we need to add a View and a Controller Action Method to return the view. We can block access to entire controllers or action methods using the FeatureGate action filter. The code looks like this.

using Microsoft.FeatureManagement.Mvc;

namespace MusicStore.Web.Controllers
{
  public class HomeController : Controller
  {
    ...

    [FeatureGate(Features.Promotions)]
    public async Task<IActionResult> Promotions()
    {
      var promoAlbums = await _albumService.PromotionalAlbumsAsync();
      return View(promoAlbums);
    }
    ...
  }
}

to the FeatureGate action filter, we need to pass a string value denoting the name of the filter. This is one of the names we define in the appsettings.json FeatureManagement section. Here I have defined a static class with string constants that contains the name of the feature flags to make it cleaner.

namespace MusicStore.Shared.FeatureManagement
{
  public static class Features
  {
    public const string Promotions = "Promotion";
    public const string PromotionDiscounts = "Promotion.Discounts";
    public const string UserSuggestions = "Suggestion.User";
  }
}

Using Tag Helper to Show/Hide UI Elements on Razor Views

If you have any UI elements you want to hide under feature flags you can use the tag helper provided in Microsoft.FeatureManagement.AspNetCore library to do that. First, you need to add the tag helper to the _ViewImports.cshtml so your views can access it.

@addTagHelper *, Microsoft.FeatureManagement.AspNetCore

Next, you can use <feature> tag helper to wrap the UI elements you want to put behind a feature flag. Let’s hide the UI elements for Suggested Albums on the home page and the title displayed on the home page depending on if the 25% discount is enabled or not.

@model HomeViewModel
@{
  ViewData["Title"] = "Home Page";
}

<div class="text-center">
  <feature name="@Features.PromotionDiscounts" negate="true"><h1 class="display-4">Enjoy the latest music from your favorite artist</h1></feature>
  <feature name="@Features.PromotionDiscounts"><h1 class="display-4">Enjoy 25% off for selected albums from your favorite artist</h1></feature>

  ...

  <feature name="@Features.UserSuggestions">
    <partial name="_UserSuggestionsPartial" model="@Model.Suggestions" />
  </feature>
</div>

Here we are using 2 feature tag helpers for the home page title. We can use negate attribute and set it to true if you want to show the content between feature tag helper when the feature is disabled. I am using a partial view wrapped in a feature tag helper to display the suggested albums for the user.

Using IFeatureManager to Programmatically Access Feature Flags

If you want to check for a feature flag in your C# code, be it from a controller or from a service class you can use IFeatureManager implementation provided by Microsoft.FeatureManager library. This interface has IsEnabledAsync() method where we can pass the name of the feature flag and see if it’s enabled or not. Here in this example, we are using it in the HomeController.cs

using Microsoft.FeatureManagement.Mvc;

namespace MusicStore.Web.Controllers
{
  public class HomeController : Controller
  {
    private readonly ILogger<HomeController> _logger;
    private readonly IAlbumService _albumService;
    private readonly IFeatureManager _featureManager;

    public HomeController(IAlbumService albumService, IFeatureManagerSnapshot featureManager, ILogger<HomeController> logger)
    {
      _albumService = albumService;
      _featureManager = featureManager;
      _logger = logger;
    }

    public async Task<IActionResult> Index()
    {
      var vm = new HomeViewModel();
      vm.Featured = _albumService.AllAlbums();

      // Check if the UserSuggestion feature is enabled.
      if (await _featureManager.IsEnabledAsync(Features.UserSuggestions))
      {
        vm.Suggestions = _albumService.UserPreferenceAlbums();
      }

      return View(vm);
    }
    ...
  }
}

Here we are injecting IFeatureManagerSnapshot to get access to a FeatureManager instance. The IFeatureManagerSnapshot provides consistency access to feature flags through the entire request. We will discuss about this in a later article. I am using IsEnabledAsync method to check for the User Suggestion feature is enabled or not before I fetch the suggested albums from the AlbumService

Now the feature flag implementation is complete. We can run the application and then change the disabled feature flags on the appsettings.json file to true and refresh the application to see the features enabled for the user.

Summary

Microsoft.FeatureManagement and Microsoft.FeatureManagement.AspNetCore is libraries that are enabling you to add easy to use and consistent feature flag implementations into your .Net Core and ASP.Net Core applications. Also being built on .Net Core IConfiguration it enables you to use multiple configuration providers to supplement your feature management capabilities. In the subsequent articles, we will dive into details about how you can use may other capabilities of Microsoft.FeatureManagement in your applications.

You Might Also Like
Comments