Feature Toggles in ASP.NET Core
I think this is a very common real-world development problem. You’re working as a team but not everyone on the team is working on the same story. There are two features actively worked on. Feature A and Feature B. Feature A is a complex one, it contains a lot of stories and tasks to complete. Feature B is relatively easy as it’s complexity is way less. Now the first story of Feature A is complete and ready for review. So a pull request is created and in the end, the story is merged to the main branch. Your team has a full-blown CI/CD pipeline in place, so a build is kicked off and the completed story is deployed to a test environment ready to be tested. But since Feature A contains a huge amount of stories, Feature A is not even near complete. So you will never promote this pipeline to production. In the meanwhile, your teammates finished Feature B and merged it to main which (again) also starting the pipeline. Feature B is really important and adds a lot of value for your customer. Now, what do you do? Bring it to production, including a half complete Feature A, or do you wait for Feature A to complete?
Feature toggles
The answer can be found in Feature Management. You can use a NuGet package called Microsoft.FeatureManagement
which helps you creating feature toggles. This allows you to add some lines to your system’s configuration in which you switch certain features on or off. So in the example above, you do want Feature A to be available on your test environment, simply because you want your testers to start working with stories as soon as they are done. But you don’t want this feature to be available in production, simply because it’s not even near complete.
Configuration
It starts with configuration, and luckily you can manipulate these configurations using ARM Templates. This allows you to configure features per environment independently. So in this case, you want to be able to enable or disable Feature A.
"FeatureManagement:FeatureA": true
Now for Feature B, it doesn’t make sense to create a feature toggle (or feature flag if you like). This feature must be available in all environments as soon as possible.
Add feature toggles
Now add the feature management package Microsoft.FeatureManagement
to your project.
dotnet add package Microsoft.FeatureManagement
In your ASP.NET project, find the Startup.cs
class and add FeatureManagement to the services:
services.AddFeatureManagement();
Feature management is now configured and running on your API.
Implementing toggles
Now when you’re running your API, Azure Functions or a business library somewhere, you can inject the IFeatureManager
and see if features are toggled on or off:
var featureIsEnabled = await _featureManager.IsEnabledAsync("FeatureA");
Also, you can use an attribute on your controller to allow execution only if the feature is enabled:
// Or the entire controller
[FeatureGate("FeatureA")]
public class HomeController : Controller
{
// ...
}
// Or on an individual action of a controller
[FeatureGate("FeatureA")]
public IActionResult Index()
{
return View();
}
You can even specify a time window for which a feature must be enabled. You could use this for example to theme your website for Christmas.
"FeatureA": {
"EnabledFor": [
{
"Name": "Microsoft.TimeWindow",
"Parameters": {
"Start": "2020/12/10 00:00:00 GMT",
"End": "2021/01/03 00:00:00 GMT"
}
}
]
}
Conclusion
These feature toggles are pretty nifty. I think the downside is that you need to change your source code and make sure your software is backward compatible if a feature is turned off. Also, once a feature is fully implemented you may need another user story to remove the feature flag and enable the thing by default. I’m using magic strings in the above example, but if you use a constant or something similar, removing the feature flag is easier.
Anyways, feature toggles and especially with Microsoft FeatureManagement will make your life as a team member of a development team a lot easier!