Monday, 9 July 2012

Feature Toggle libraries for .NET

The idea of "Feature Toggles" is described in detail by Martin Fowler. Essentially these give you the ability to enable/disable parts of your application via configuration.

It's a simple enough concept that you can quite easily do this in code. Just add a new setting to your app.config file:

<appSettings>
    <add key="Feature.Toggle1" value="True"/>
</appSettings>

And then within your code, check the config value to enable the feature:

if (bool.Parse(ConfigurationManager.AppSettings["Feature.Toggle1"]))
{

}

Ideally you'd make that check a bit more robust, but you get the idea!

Alternatively, you might want to use one of these libraries that implement feature toggling. I searched for .NET feature toggle libraries and found these four. Coincidentally they are all hosted on Github, and all but nToggle are available as NuGet packages.

NFeature

https://github.com/benaston/NFeature

NFeature requires you to create an enum which defines all the feature toggles. It then generates extension methods such that you can check the config setting for a feature. Features are configured through a custom section in the .config file. Features can optionally be configured to depend on other features, and to have availability times set.

<configSections>
    <section name="features" type="NFeature.Configuration.FeatureConfigurationSection`1[[NFeatureTest2.Feature, NFeatureTest2]], NFeature.Configuration" />
</configSections>

<features>
    <add name="MyFeature" state="Enabled" />
    <add name="MyOtherFeature" state="Previewable" />
    <!-- will only be available to users who meet the feature-preview criteria -->
    <add name="MyOtherOtherFeature" state="Disabled" />
</features>
public enum Feature
{
    MyFeature,
    MyOtherFeature,
    MyOtherOtherFeature,
} 

...

if ( Feature.MyFeature.IsAvailable( featureManifest ) )
{
    //do some cool stuff
}

NFeature appears to be actively maintained with recent commits.

FeatureToggle

https://github.com/jason-roberts/FeatureToggle

FeatureToggle provides base classes from which you inherit for each feature toggle you want to implement. These toggles are configured in the <appSettings/> section in the .config file.

<appSettings>
   <add key="FeatureToggle.MyAwesomeFeature" value="false" />
</appSettings>
public class MyAwesomeFeature : SimpleFeatureToggle {}

...

if (!MyAwesomeFeature.FeatureEnabled)  
{
   // code to disable stuff (e.g. UI buttons, etc)
}

FeatureToggle also has support for WPF and Windows Phone apps.

It is actively maintained with recent commits.

FeatureSwitcher

https://github.com/mexx/FeatureSwitcher

In FeatureSwitcher, toggles are created by implementing the IFeature interface. You then use the Feature<> generic class to test whether a particular toggle is enabled.

Toggles are configured in the .config file via custom sections.

<configSections>
  <sectionGroup name="featureSwitcher" type="FeatureSwitcher.Configuration.SectionGroup, FeatureSwitcher.Configuration">
    <section name="default" type="FeatureSwitcher.Configuration.DefaultSection, FeatureSwitcher.Configuration"/>
    <section name="features" type="FeatureSwitcher.Configuration.FeaturesSection, FeatureSwitcher.Configuration"/>
  </sectionGroup>
</configSections>
<featureSwitcher>
  <default featuresEnabled="true"/>
  <features>
    <feature name="FeatureSwitcher.Examples.BlueBackground" enabled="true"/>
  </features>
</featureSwitcher>
class BlueBackground : IFeature {}

...

if (Feature<Sample>.Is().Enabled)
{

}

FeatureSwitcher is actively maintained with recent commits.

nToggle

https://github.com/SteveMoyer/nToggle

nToggle uses a custom section in the .config file. The examples given show usage with a WebForms app, though it should work with all kinds of applications.

<configSections>
  <section
    name="nToggle"
    type="nToggle.Configuration.ToggleConfigurationSection"
    allowLocation="true"
    allowDefinition="Everywhere"
    />
</configSections>

<nToggle>
  <toggles>
    <add name="TestFeatureOn" value="True"/>
    <add name="TestFeatureOff" value="False"/>
  </toggles>
</nToggle>
<%@ Register assembly="nToggle" namespace="nToggle" tagprefix="nToggle" %>
<nToggle:WebFeatureToggle ID="FeatureToggle1" EnabledBy="TestFeatureOff" runat="server" >
    <span id="enabledby"> Feature Turned Off</span>
</nToggle:WebFeatureToggle>
protected void Page_Load(object sender, EventArgs e)
{
    WebFeatureToggle1.RunActionWhenEnabled(CodeToRunIfEnabled);
}

protected void CodeToRunIfEnabled()
{
    //your code
}

nToggle has not been updated for 7 months at time of writing.

4 comments:

Jan Vandenbussche said...

Which framework do you recommend?
Which one did you end up using?

David Gardiner said...

In the end I ended up with the first option of doing it myself. None of the others worked simply enough.

-david

Jan Vandenbussche said...

Thank you, David, for answering.
I will check out what some of the frameworks have to offer, but I will keep the option open to roll my own, specific to our needs.

Jan Vandenbussche said...

I ended up writing a small wrapper around NFeature exposing only its most basic features (for now). This should make switching to a different framework later (or implementing our own) painless in the future.