How to Toggle Features in C# with Feature Flags

This blog post was contributed by Tuan Nguyen, Software Developer at Getty Images.

Using feature flags to release new features to customers is a powerful technique. I have been using feature flags for many years to release features or changes to production safely and with the peace of mind. The releases are done without any ceremony, and the features aren’t visible to customers until we turn the feature flag on. Using feature flags to toggle functionality in .NET Core apps is easily achievable using a feature flag management platform.

In this tutorial, I’ll show you how to toggle features on demand in a simple web application using Unlaunch to create and manage feature flags. We’ll also see how to show or hide our features with a click of a button, without merging branches, rollbacks or deploys.

Feature Flags

Feature flags allow developers to control who sees new features irrespective of code deployment. For example, developers can deploy a new feature to production environment and keep it hidden from all users (except themselves.) This way, they can do testing on real systems, and when the management is ready to release the feature, they can turn on the feature flag to let the users in on it. To me, here are some of the benefits of using feature flags:

  • Developers eliminate some of the risk knowing they can roll things back instantly if things go wrong. On a few occasions, I rolled back features because of negative impact to KPI we didn’t consider before or one of the underlying system wasn’t quite ready.
  • Developers can launch the feature on production behind feature flag and show it to product or marketing team for their feedback.
  • QA in production. This doesn’t mean that we skipped testing on the ‘Dev’ environment, but rather launching the feature on production just for the development team give extra boost of confidence. It also allowed testing with real data which is not always up to date on ‘Dev’ environment.
  • Gradually roll features out starting with a small percentage of users. This is also known as canary releases.

Basics of Feature Flags

A feature flag is a simple object that has a Boolean value or variations such as “on” or “off” Based on the value of the variation, you either do one thing or the other.

string feature = getFeatureFlag("FLAG-ID");// Get feature flag

if (feature == "on") 
{
    // show new code 
} 
else 
{
    // show old code
}

You can use a use a config file (appsettings.json) or a database to keep feature flags. You can also use a number of feature flag platforms which provide a web UI to manage and control feature flags and SDKs to make it easy to integrate across the stack.

Implementing Feature Flags in .NET Core

I’ll show you how to implement and use feature flags in .NET Core and ASP.NET. I will be using the Unlaunch SDK for.NET to manage and retrieve feature flags from my code. We’ll use the eShop Web application. Our imaginary use case (inspired from real-life) is to change the sort order on our store. We want to show items in reverse order.

eShopWeb - Normal sort order

I’ll show you how to implement the new feature (sort items in reverse order) and put it behind a feature flag. When the feature flag is turned “on”, the items will be sorted in reverse order. If the feature flag is turned “off”, the sort order will not change.

Before Your Get Started

Register an Unlaunch Account

Go to Unlaunch.io and create a free account. As part of sign up, create a new project. (The name of the project should match that of your application. I named my project ‘eShopWeb’.) Next, I created a new feature flag called ‘catalog_reverse’. Leave everything to its default value. Make sure you enable the flag by clicking on the “Enable Flag” button in the top right corner. To make the feature flag return “on” variation (to signal that we should show the feature to all users), choose “on” variation under “Default Rule”.

C# feature flag returning on variation for all users

Access the Feature Flag from .NET Core Application

Install the Unlaunch SDK

To use the feature flag ‘catalog_reverse’ in our application, we need to integrate the Unlaunch .NET SDK.

Install the Nuget package or run:

Install-Package unlaunch

Initialize Unlaunch Client as a Singleton

In src/Web/Startup.cs, initialize the Unlaunch client. The client will download the feature flag right away and will poll for changes every 60 seconds. You can customize the polling interval, but in our case, 60 seconds works great. A number of feature flag platforms like LaunchDarkly uses a streaming architecture but I prefer polling to avoid any extra overhead and in most cases, it is okay to wait up to a minute to disable the feature if the flag is turned off using the web UI.

services.AddSingleton<IUnlaunchClient>(UnlaunchClient.Create("YOUR_SDK_KEY"));
services.AddTransient<UnlaunchService>();

To find your SDK key, in the Unlaunch web UI, and click on “Settings” in the sidebar. Copy the Server Key for the environment you’re working with (Production in my case.) Additional information: Unlaunch provides 3 different types of SDK keys for security purposes. For example, the “Browser Key” is for client-side SDKs like React that run on client side. To access feature flags with this SDK key, you must update flag settings to make it available on client-side.

Find Unlaunch SDK Keys

Evaluate feature flag and get “on” or “off” variation

I created a new service for Unlaunch called UnlaunchService within the application to handle feature flag logic in there and inject this service in other places.

namespace Microsoft.eShopWeb.Web.Services
{
    public class UnlaunchService
    {
        private const string CatalogReverseFlag = "catalog_reverse";

        private readonly IUnlaunchClient _client;

        public UnlaunchService(IUnlaunchClient client)
        {
            _client = client;
        }

        public bool IsCatalogReverseFlagEnabled(string userIdentity)
        {
            var variation = _client.GetVariation(CatalogReverseFlag, userIdentity);
            return variation == "on";
        }
    }
}

I created a wrapper function (IsEnabled) to return whether the feature flag is enabled or not. It takes a string argument called userIdentity. This is important when doing gradual or phased rollouts as Unlaunch SDK uses hash of userIdentity to determine whether to show the feature or not to a particular user. For this example, this argument is not used because we are turning the flag on or off for all users. But we’ll pass it anyways because we’ll be using it later.

Then in my Index.cshtml, I check if the feature flag is enabled or not and if enabled, I sort the items in the reverse order.

<div class="esh-catalog-items row">
    @{
        if (UnlaunchService.IsCatalogReverseFlagEnabled(HttpContext.Connection.RemoteIpAddress.ToString()))
        {
            Model.CatalogModel.CatalogItems.Reverse();
        }

        foreach (var catalogItem in Model.CatalogModel.CatalogItems)
        {
            <div class="esh-catalog-item col-md-4">
                <partial name="_product" for="@catalogItem" />
            </div>
        }
    }
</div>

As we can see, items in the shop are reverse sorted when the feature flag is turned “on”.

eShopWeb - Reverse sort when feature flag is on

Targeting User Segments with Feature Flags

Targeting Specific Users By ID

Suppose you want to turn the feature on only for internal users so they can see how things look. For example, if I wanted to keep the feature off for everyone and only enable it for one of my colleagues whose working from home, I can target by IP address. (Alternatively, you can also target users by other criteria e.g. all users whose email address ends with [email protected], but if you recall, our shop is visible to logged our users and we’re passing IP address as identity.)

feature flag IP address targeting in C#

Targeting by Geo-location

Often times, we roll out feature starting with countries that would have limited impact on revenue or other KPIs if things go south. For example to target everyone from Germany (DEU) and Austria (AUT). This often allow to learn the behavior and impact of a new feature before opening it up for broader audience. To do this, create a new Attribute in Unlaunch of type “Set” and call name “country”.

feature flag targeting by country in C#

To make this work, in our code we’d have to pass an additional attribute that contains user’s country so the SDK can decide which variation to show. In the Unlaunch service class, I updated the isEnabled to resolve user country by IP and pass it to the SDK.

public bool IsEnabled(string userIdentity)
{
    var variation = _client.GetVariation(
        FlagKey, 
        userIdentity
        UnlaunchAttribute.NewSet("country", GetLetterCountryCodeByIP(userIdentity)),
    );

    return variation == "on";
}

Targeting by Email

Suppose, we want to target all logged in users in your company. We can define a targeting rule to show the feature to everyone whose email ends with @@yourcompanydomain.com.

feature flag targeting by email in C#

You’d have to start passing the email address to the SDK so it can make the decision.

public bool IsEnabled(string userIdentity, string email)
{
    var variation = _client.GetVariation(
        FlagKey, 
        userIdentity
        UnlaunchAttribute.NewString("email", email),
    );

    return variation == "on";
}

I just gave you a few examples that I’ve been using to target segments using feature flags. The possibilities are endless and in my opinion, this is where feature flags truly shine. You can release a feature on production and turn in on only for specific users (just your product manager or QA engineer,) or everyone in the company, or everyone in certain countries, etc. Try it out and have fun with it.

Summary

Feature flags are easy to set up and add a lot of flexibility to your application. Even if you use a feature flag service provider or create your own solution, I’m confident that your team will appreciate the idea of decoupling feature releases from code deployments because it removes a major source of stress.

GitHub Repo

Here’s the complete source code used in this blog post is available on GitHub. Here’s the commit with comments describing changes: https://github.com/tnguyenquy/eShopOnWeb/commit/116ee293f79b7bac52fd7957dfa2feb033384c2b.

Learn More

#feature-flags #ci-cd

You May Also Enjoy


If you like this post, please share using the buttons above. It will help CodeAhoy grow and add new content. Thank you!


Speak Your Mind