Implementing Feature Toggles in a .Net MVC Application

This is part 2 of a set of posts on feature toggles (part 1 is here). These are some example some code snippets (C#) based on techniques I have used to implement feature toggle systems in .Net applications. This example assumes that Unity is used for dependency injection. A real-world implementation would likely include a database for feature storage (with admin screens) and caching of feature checks for performance.

All Known Features

First, you need a master list of known features:


public enum FeaturesEnum
{
    CustomiseUserWorkspace,
    CancelSubscription,
    NewAwesomeThing
    //etc
}

Feature-Checking Code

Now you’re going to want a central authority for the current feature toggle state – a FeaturesService, and some kind of FeatureStore (not shown, add your own implementation). The FeatureStore implementation could be a config file or a database (hence the “ToggleFeature” method).


    public interface IFeaturesService
    {
        bool IsEnabled(FeaturesEnum feature);

        void ToggleFeature(FeaturesEnum feature, bool isEnabled);
    }

    public class FeaturesService : IFeaturesService
    {
        private readonly IFeatureStore _featureStore;

        public FeaturesService(IFeatureStore featureStore)
        {
            _featureStore = featureStore;
        }

        public bool IsEnabled(FeaturesEnum feature)
        {
            var featureRecord = _featureStore.GetFeature(feature);
            return (featureRecord == null) ? false : featureRecord.IsEnabled;
        }

        public void ToggleFeature(FeaturesEnum feature, bool isEnabled)
        {
            _featureStore.SetFeature(feature, isEnabled);
        }
    }

    public class FeatureRecord
    {
        public FeaturesEnum FeatureType { get; set; }
        public bool IsEnabled { get; set; }
    }

 

That’s all you need for basic feature toggle infrastructure. Now you need to add code to check those feature toggles.

Checking Feature State

First, to check for a feature and branch the code (eg. in a controller):


    public class HomeController : Controller
    {
        private readonly IFeaturesService _featuresService;

        public HomeController(IFeaturesService featuresService)
        {
            _featuresService = featuresService;
        }

        public ActionResult Index()
        {
            if (_featuresService.IsEnabled(FeaturesEnum.NewAwesomeThing))
            {
                //Do the shiny new thing
            }
            else
            {
                //Do the boring old thing
            }

            return View();
        }
    }

If you want to toggle UI elements (or hide the button that launches your new feature), add some HTML helper code:


    public static class FeaturesHelper
    {
        private static IFeaturesService _featuresService = null;
        private static IFeaturesService FeaturesService
        {
            get
            {
                if (_featuresService == null)
                {
                    _featuresService = UnityConfig.Container.Resolve();
                }
                return _featuresService;
            }
        }

        public static bool IsFeatureEnabled(this HtmlHelper helper, FeaturesEnum feature)
        {
            return FeaturesService.IsEnabled(feature);
        }
    }

And make a single-line check:


@if (Html.IsFeatureEnabled(FeaturesEnum.NewAwesomeThing))
{
<p>New awesome markup</p>
}

And finally, putting security checks on the UI is never enough, so you might want some access control attributes:


    public class FeatureEnabledAttribute : AuthorizeAttribute
    {
        private readonly FeaturesEnum _feature;

        public FeatureEnabledAttribute(FeaturesEnum feature)
        {
            _feature = feature;
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            var featuresService = UnityConfig.Container.Resolve();
            return featuresService.IsEnabled(_feature);
        }
    }

Now you have another one-line check you can use to block access to controllers or methods:


    [FeatureEnabled(FeaturesEnum.NewAwesomeThing)]
    public class AwesomeController : Controller

Notes

I favour using enums over strings for my known features, because then I don’t have to worry about run-time typos suddenly checking for a brand new unknown feature. It also makes finding and removing features easier. And depending on language used, it might even be easy to document the features using decoration attributes (eg. adding longer descriptions for an admin system).

Any “master record” of which features exist should live with the code. You’re going to need to provide this to any admin system you build (via reflection, API call, etc).

When it comes to unit testing, it’s probably worth your while to actually implement a “FakeFeatureService” that’s just an in-memory dictionary and use the standard ToggleFeature() methods, rather than going with a mocking framework. Also, if you go with enums for your list of known features, the list is going to change frequently. To prevent brittle tests, don’t use a specific feature when testing your feature toggle framework code, just write a little builder/helper to give you a random valid feature enum from the list of current features.

Leave a comment