Skip to content

The Comprehensive Guide To Feature Management In ASP.NET Core

The comprehensive Guide to Feature Management in ASP.NET Core

Feature management in ASP.NET Core is released in 2019. Some of you may know about the feature flags and some may not even be heard of them.

In this post, we will see what is/are feature management or feature flags and how they are useful. And we will create a new feature to demonstrate the use of feature flags and we will also see the different ways we can access feature management in the code.

What is Feature management?

Feature/feature flag management is the ability to show/hide a feature on demand.

Simply put, feature flags are like having a switch to control features which should either be shown or hidden to the user based on the flag value

A feature flag is also called a feature switch, feature toggle, feature gate, feature flipper, or conditional flipper.

Why do we need feature flags?

Assume that we have a brand new feature release for our product. But, the users are not aware of the feature and we’d want to show the feature somewhere on the product homepage and test them internally on production as well.

One way we could achieve this is to create a new sandbox environment and replicate the production data to the sandbox environment and test it.

That works! Now, let’s say we have a defect in the feature in production and it broke the whole thing. We’d have to redeploy the last best working version onto production.

What if I say that we can do it in real-time with just a flip of a flag? Yes, it’s feature flags that get the job done.

With feature flags, we can continuously develop the features and merge them to the main branch and deploy it to production. And in real-time we can show them or hide them based on the need.

These feature flags are more useful for product owners and testers who will test features in all environments.

Let’s dive in and understand feature management.

Adding Feature Management package in ASP.NET Core

Microsoft created a feature management package for ASP.NET Core.

As always you can install the package in a few different ways

  • Head over to the Nuget Package Manager in the Project context menu and search for Microsoft.FeatureManagement and install it
  • Or You can also install it with the Package Manager console in Visual Studio with this command Install-Package Microsoft.FeatureManagement -Version 2.5.1
  • Or you can also install it with .NET CLI dotnet add package Microsoft.FeatureManagement --version 2.5.1

Configuring Feature management in ASP.NET Core app

After installing the feature management package from NuGet, we have to add the feature management service in our ConfigureServices method in our startup class

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();

    services.AddFeatureManagement();
}

For the purpose of this article, I’ve created a new ASP.NET Core project. So, my ConfigureServices method has fewer services registered. You may have more services added to it. But, the order of adding feature management doesn’t matter.

Declaring Feature flags in appsettings.json

Now, let’s add the feature management section to the app settings file.

"FeatureManagement": {
    "CoolFeature": false,
    "SecretFeature": true
}

We declared our feature flags within FeatureManagement the section. The name of the section should be FeatureManagement as it is a convention.

If we give the section name other than FeatureManagement it won’t be picked by our IFeatureManager interface and we will get false as a value for all of our feature flags.

Every property within the FeatureManagement is a feature flag. In our configuration we have feature flags for CoolFeature and SecretFeature. We could also have filters within a feature (that’s a separate topic may be another article)

Setting true/false for a feature flag will return true/false when queried with IFeatureManager interface.

Consuming the feature flags in the ASP.NET Core Pages

Now we have our feature flags set up in appsettings.json file. Now, it’s time to query them to see if they are working.

Let’s head over to Index.cshtml.cs file and inject IFeatureManager into the IndexModel class.

Here is how the IndexModel.cs file looks like

public class IndexModel : PageModel
{
    private readonly ILogger<IndexModel> _logger;
    private readonly IFeatureManager _featureManager;

    public IndexModel(ILogger<IndexModel> logger, IFeatureManager featureManager)
    {
        _logger = logger;
        _featureManager = featureManager;
    }

    public async Task OnGet()
    {
        var secretFeature = await _featureManager.IsEnabledAsync("SecretFeature");
        _logger.LogInformation($"Secret Feature value: {secretFeature}");
    }
}

In the OnGet() method, we’ve logged our SecretFeature value. If we run the app and go to the Index page, we should see the log writing the flag value.

Fig 1: Feature flag value logged onto console

Adding a feature

Let’s add a secret feature to our home screen. So that when our SecretFeature is enabled we can see it on our index/home page.

So, let me create a partial view that holds the work done in that feature.

<div class="card" style="width: 400px; height: 400px;">
    <img src="https://images.unsplash.com/photo-1483706600674-e0c87d3fe85b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1507&q=80" class="card-img-top" alt="...">
    <div class="card-body">
        <h5 class="card-title">Secret Feature</h5>
        <p class="card-text">work in progress...</p>
    </div>
</div>

The code in our partial view is essentially a bootstrap card component with an image.

Here is what the card component looks like.

Adding secret feature in feature management
Fig 2: secret feature

Toggle the feature flag on a feature

we have to add conditional rendering in order to show this secret page only when SecretFlag is true .

Here is our Index.cshtml file

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

@if (Model.SecretFeatureEnabled)
{
    <partial name="_SecretPage" />
}

As you can see, based on the value of SecretFeatureEnabled we will show or hide our feature.

SecretFeatureEnabled is a property added to our IndexModel page which preserves the feature flag value

And here is our code behind file.

public class IndexModel : PageModel
{
    public bool SecretFeatureEnabled { get; set; }
    // ... other private variables and constructor
    
    public async Task OnGet()
    {
        SecretFeatureEnabled = await _featureManager.IsEnabledAsync("SecretFeature");
        _logger.LogInformation($"Secret Feature value: {SecretFeatureEnabled}");
    }
}

And we are done with our setup. Let’s run. Here is the demo

feature management demo in ASP.NET Core

That’s it. We are able to toggle between true/false and able to see or hide our secret feature based on that.

Here is the source code on GitHub

Why not check the feature flag in cshtml itself

For the above demo, maybe I did too much to get the feature flag value from the code behind(IndexModel.cshtml.cs) to the cshtml file (IndexModel.cshtml).

We can also add the feature flag value to either ViewBag or ViewData and based on it we can render the partial view.

But, there are a few other ways to access the feature flag value directly in the cshtml file.

Injecting IFeatureManager in cshtml with @inject

Well, we can inject IFeatureManager into the view itself. Here is how it’s done.

@page
@inject Microsoft.FeatureManagement.IFeatureManager _featureManager;
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

@if (await _featureManager.IsEnabledAsync("SecretFeature"))
{
    <partial name="_SecretPage" />
}

This may look crazy to you if you are new to this. But yes, ASP.NET Core supports dependency injection into views with @inject.

With this approach, we don’t need any changes to do in the Index.cshtml.cs file any more.(at least for this feature flag)

Here is the source code on Github

using the Feature Tag Helper to show or hide the feature flag

We can also use the feature tag helper in ASP.NET Core to do the same thing.

<feature name="@FeatureFlags.SecretFeature">
    <partial name="_SecretPage" />
</feature>

In order for this to work, we have to install Microsoft.FeatureManagement.AspNetCore package via NuGet and add it in _ViewImports.cshtml file like this.

@addTagHelper *, Microsoft.FeatureManagement.AspNetCore

We can also negate the feature flag value with negate attribute on the <feature> tag helper.

<feature name="@FeatureFlags.SecretFeature" negate="true">
 Feature will be shown if SecretFeature is disabled
</feature>

We can also use <feature> tag helper to show if all or any of the feature flags are enabled

<feature name="SecretFeature, CoolFeature" requirement="All">
    <p>This can only be seen if 'SecretFeature' and 'CoolFeature' are enabled.</p>
</feature>
<feature name="SecretFeature, FeatureB" requirement="Any">
    <p>This can be seen if 'SecretFeature', 'CoolFeature', or both are enabled.</p>
</feature>

And the source code of the feature flag with feature tag helper on Github

Summary

  • We saw what is feature management and why we need it
  • We created a secret feature that is behind a feature flag
  • We configured our feature flags in appsettings.json and saw how to access the feature flag value with IFeatureManager interface in csharp code
  • And learned different ways we can directly access the feature flag value in the razor template.

Infographic

The below infographic is just to give a glimpse of what feature management in asp.net core is. If you like this, please feel free to share this across your network.

The Comprehensive Guide to Feature Management In ASP.NET Core

References

2 thoughts on “The Comprehensive Guide To Feature Management In ASP.NET Core”

  1. It works fine if you have single service. Difficulties came when we have several microservices, choreography, that process one user request and has to use same feature flag through all microservices. Is there any API way how to get feature flag value at particular time in the past, when the first microservice started processing user request?

    1. Hey Vitalii,

      Thanks for your comment.

      In microservices world you can leverage feature flags by storing them in a key vault (Azure) or Parameter Store (AWS) or you could build a API around feature management which will return whether the feature is turned ON/OFF and query the API to get the feature value.

Leave a Reply

Your email address will not be published.