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?
- Why do we need feature flags?
- Adding Feature Management package in ASP.NET Core
- Configuring Feature management in ASP.NET Core app
- Declaring Feature flags in appsettings.json
- Consuming the feature flags in the ASP.NET Core Pages
- Adding a feature
- Toggle the feature flag on a feature
- Why not check the feature flag in cshtml itself
- Summary
- Infographic
- References
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.
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.
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
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 withIFeatureManager
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.
References
- Feature Management.
- Complete source code of this article on GitHub.
- Light switch animation from Pablo Danielli.
- Secret image from unsplash.com by Kristina Flour
Karthik is a passionate Full Stack developer working primarily on .NET Core, microservices, distributed systems, VUE and JavaScript. He also loves NBA basketball so you might find some NBA examples in his posts and he owns this blog.
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?
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.