Easy custom configuration section in the App.config

There’s a couple of ways to handle configuration sections within the App.config file. The simplest (in my opinion at least) is by inheriting from the ConfigurationSection, ConfigurationElement and so on. The alternative would be to implement the IConfigurationSectionHandler, but that’s for another post.

So here’s a simple scenario…

I have a simple Tibco RV monitor application. My own implementation, of sorts of TIB’s tibrvlisten.exe, but with the ability to log and filter messages etc. So I want to create a simply configuration section for supplying a list of the filters to plugin to the application (similar to the way some IoC libraries work).

Here’s a sample of the App.config that I want

<configSections>
   <section name="FiltersSection" type="RvMonitor.FiltersSection, RvMonitor"/>
</configSections>

<FiltersSection>
   <Filters>
      <add type="Filters.ClassNameFilter, Filters" />
      <add type="Filters.ClassNameFilter, Filters" />
   </Filters>
</FiltersSection> 

Let’s start at outside and work inwards.

So quite obviously (from the configSections) we’re going to require a FiltersSection object. We need to derive our FiltersSection from the system.Configuration.ConfigurationSection class. This class will then have a ConfigurationProperty named Filters, which translates to our Filters element. This will be a collection or more specifically a type derived from the ConfigurationElementCollection. Let’s take a look at the code for the FiltersSection first

public class FiltersSection : ConfigurationSection
{
   [ConfigurationProperty("Filters")]
   [ConfigurationCollection(typeof(FiltersCollection),
      AddItemName = "add", 
      ClearItemsName = "clear", 
      RemoveItemName = "remove")]
   public FiltersCollection Filters
   {
      get { return (FiltersCollection)this["Filters"]; }
   }
}

Before we look at the very simple implementation of FiltersCollection let’s review this code.

The ConfigurationProperty simply defines the name of the element which our collection resides within. The ConfigurationCollection attribute then tells the ConfigurationManager the type of the collection and defines the elements to add, clear and remove items. We’re actually only interested in adding filters, after all you can just remove them from the App.config if you want to clear or remove items. The “add” name can be changed and relates to the add elements within the Filters element of the configuration, i.e.

<add type="Filters.ClassNameFilter, Filters" />

So let’s create a simply ConfigurationCollection

public class FiltersCollection : ConfigurationElementCollection
{
   protected override ConfigurationElement CreateNewElement()
   {
      return new FilterType();
   }

   protected override object GetElementKey(ConfigurationElement element)
   {
      return element;
   }
}

I’ve shown the bare minimum required to implement a ConfigurationElementCollection. Obviously we need some way to create instances of our element type (i.e. that type that our “add” element creates). Here we create a FilterType via the CreateNewElement method. I’ve not bothered creating an element key, so I’m just returning element from GetElementKey, but you might prefer to use something like

protected override object GetElementKey(ConfigurationElement element)
{
   return ((FilterType)element).TypeName;
}

Finally let’s look at the extremely simple FilterType which derives from the ConfigurationElement type.

public class FilterType : ConfigurationElement
{
   [ConfigurationProperty("type", IsRequired = true)]
   public string TypeName
   {
      get { return (string) this["type"]; }
      set { this["type"] = value; }
   }
}

Notice how in this class and the FiltersSection class we use the built in Hashtable to store our actual property data.

And that’s about it, oh, except how to use the code within our app. Here’s the code

var filtersSection = (FiltersSection)ConfigurationManager.GetSection("FiltersSection");

and there we have it, pretty simple.