Wednesday, February 18, 2015

The Feature Flags Pattern





I was listening to Episode 1101 of the podcast Dot Net Rocks. Jez Humble was talking about the concept of Feature Toggles or Feature Flags. Feature Switches? While the term has some opinionated definitions, the concept that I found most interesting was the idea of deploying software with the new features initially disabled, or switched off by some mechanism. After you think the feature is ready for production, switch on the feature. If there is an issue, you don't have to roll back the version or deploy another release, just switch the feature back off again and replace its .dll. Didn't get enough debug information? Switch the feature back on and let a few crash reports trickle in and then switch it back off. If you feature is particularly processor or network intensive, you can perform load testing by slowly releasing the features to select clients or only part of the population/userbase.

While I personally choose an SQL table for my approach to storing the toggle switches (internal business app), one could use the application's .config file. An application could pull the settings from a .config file on a networked drive as a way of controlling multiple application instances by making one changed to a centralized location. Below I show a minimalist implementation by creating a Dictionary from the <appSettings> in a App.config file.

Behold:


public static Dictionary<string, bool> GetFeatureFlags()
{
  return ConfigurationManager.AppSettings.AllKeys.ToDictionary(s => s, IsFlagSet);
}

public static bool IsFlagSet(string settingName)
{
  bool result = false;
  bool.TryParse(ConfigurationManager.AppSettings[settingName], out result);
  return result;
}

Of course with a dictionary you have to be careful that you don't try an access a column that does not exist with the indexer, so you might be better off using IsFlagSet(string), which will never throw. Although this is of limited use (AppSettings is already a NameValueCollecion), perhaps you can make use of this generic function I wrote that uses generics to convert AppSettings into a dictionary with the type of the value being the generic:


public static Dictionary<string, T> GetDictionary<T>()
{
 return ConfigurationManager.AppSettings.AllKeys.ToDictionary<string, string, T>(s => s, GetSetting<T>);
}

public static T GetSetting<T>(string settingName)
{
  try
  {
    T result = (T) Convert.ChangeType(
      ConfigurationManager.AppSettings[settingName],
      typeof (T)
    );
    if (result != null)
    {
      return result;
    }
  }
  catch { }

  return default(T);
}

Please note that swallowing an exception ("catch { }") is typically considered poor form. In this particular scenario, I am aware of the possible exceptions that can be thrown by this code and I want the code to return the default(T) in this scenario and never throw.



Wednesday, February 4, 2015

EditLabel UserControl



EditLabel is editable Label control, who's text can be modified at run-time by double-clicking on it. Under the hood, it contains a Label control and TextBox control. It works like a Label control until you double-click it with the mouse. When double-clicked it enters 'edit-mode' where a TextBox overlays the Label. The control will AutoSize to the characters you type in the TextBox, updating the Label's size at the same time. You can leave the control's edit mode by hitting either enter, the escape key, or letting the control lose focus. After editing, the control acts like a label again, with the updated text. You can check out the code for the EditLabel project here on my GitHub.

The EditLabel isn't too interesting by itself, but I wanted to blog about it for all the interesting attributes that I never knew about until I started getting into designing controls, and controlling how controls are displayed in the designer window in visual studio.

The first thing my EditLabel control needed was and event that the parent form could subscribe to know when the text changed. Creating the event simply isn't enough. If you want the event to show up in the Visual Studio's Form Designer when you click on events, you need to add the Browsable and EditorBrowsable attribute. This will make is show up in the designer. You can control the description that appears as well as what category it shows up under when viewing events/properties in the Categorize view as opposed to Alphabetical view by using the Description and Category attributes respectively:

[Category("Property Changed")]
[Description("Event raised when the value of the Text property is changed on Control.")]
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
public new event EventHandler TextChanged;

There is also the notion of default events. That is, the event for which a handler is added when you double click the control in the designer. For example, when you double click a TextBox, it automatically adds the TextChanged event, instead of, say, the KeyDown event. To make an event the default event, add the DefaultEvent attribute at the control's class-level declaration:

[DefaultEvent("TextChanged")]
public partial class EditLabel : UserControl
{
   ...

Another thing I wanted was the Text property. Like a Label or a TextBox control, I wanted a public Text property that could be edited at design time. However, every time I re-built the project, the text would get reset to the default. As it turns out, if you want modifications to properties to be persisted, it must be serialized to the MainForm.Designer.cs, or whatever the auto-generated Designer.cs file is. In order to tell the designer to serialize changes made at design time to Designer.cs file, you have to add the DesignerSerializationVisibility attribute above the property. Here is the attributes and declaration for the Text property:

[Category("Appearance")]
[Description("The text associated with the control.")]
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text
{
   get { return ctrlLabel.Text; }
   set { ChangeText(value); }
}

You can view the full EditLabel.cs here, or view the entire EditLabel project here.