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.
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.
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.
Microsoft created a feature management package for ASP.NET Core.
As always you can install the package in a few different ways
Install-Package Microsoft.FeatureManagement -Version 2.5.1
dotnet add package Microsoft.FeatureManagement --version 2.5.1
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.
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.
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.
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.
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
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.
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
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
appsettings.json
and saw how to access the feature flag value with IFeatureManager
interface in csharp codeThe 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.
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.
In this post, we’ll see how to test gRPC Server applications using different clients. And… Read More
In this post, we'll create a new gRPC project in ASP.NET Core and see what's… Read More
In this blog post, we’ll see how to run dotnet core projects without opening visual… Read More
Programmatically evaluating policies is useful when we want to provide access or hide some data… Read More
We saw how we could set up policy-based authorization in our previous article. In this… Read More
What is policy-based authorization and how to set up policy-based authorization with handlers and policies… Read More
This website uses cookies.