Most of the code examples below are by Nick Chapsas, his youtube video Dynamically enabling features with Feature Flags in .NET Core 3.1 was super helpful.
All the code snippets below are available at https://github.com/carlpaton/FeatureFlagDemo
What is a feature?
In its simplest form, a feature
is some new behavior in your application. Having feature managment allows us to iteratively ship small changes to production which are essentially hidden / turned off. We can turn these on based on some predicate, its common to use a claim from the authenticated users JWT in the logic.
Examples
1 | if `user-email` ends with `@gmail.com` then return true |
Feature flags in an ASP.NET
.Net supports feature flags in the following namespaces
Config Driven
We use appsettings.json as a home for the config.
Custom Flag
This is a great way to integrate with Launch Darkly as the filter would call out to launchdarkly.com and it would manage the flag based on what you have configured.
See Custom Flag Implementation
code example below for this configuration.
Simple on/off
Here NewFeatureAFlag
is on and NewFeatureBFlag
is off.
1 | "FeatureManagement": { |
Time Window
Here HappyHolidaysFlag
is on only between given time windows.
1 | "FeatureManagement": { |
Percentage
Although .Net supports this out the box a percentage calculation should not really be the responsability of the application instance. If this was running in a cluster (so several nodes running in K8’s) it would make sense for the load balancer to make this decision.
1 | "FeatureManagement": { |
Custom Flag Implementation
- Create the configuration, here the flag is
BrowserFlag
and the filter isBrowserFeatureFilter
which configurationParameters:AllowedBrowsers
. The configuration can be anything and just needs to match
1 | "FeatureManagement": { |
- Create the options file as Features/BrowserFeatureOptions.cs, this is not automagically resolved but needs to be done using the filters context.
1 | namespace FeatureFlagDemo.Features |
- Create the the filter as Features/BrowserFeatureFilter.cs, the alias
BrowserFeatureFilter
needs to match the name in the appsettings.json configuration. The interfaceIFeatureFilter
comes from the namespaceMicrosoft.FeatureManagement
and has a single method EvaluateAsync which will be called by the framework.
1 | using Microsoft.AspNetCore.Http; |
- Dependency injection
Add a default implementation for the Microsoft.AspNetCore.Http.IHttpContextAccessor
this is the httpContextAccessor
instance injected into the filter.
1 | public void ConfigureServices(IServiceCollection services) |
Finally resolve the feature managment services
1 | services.AddFeatureManagement() |
- Validate the flag
BrowserFlag
in code
Controller action result annotation
If the flag passes then the endpoint will be served else it will return 404 Not found.
1 | namespace FeatureFlagDemo.Controllers |
Using tag helpers in the view
1 | @using Microsoft.FeatureManagement |
Using conditions in the view
1 | @if (await FeatureManager.IsEnabledAsync("BrowserFlag")) |