More custom configuration in the App.config (using IConfigurationSectionHandler)

In the previous post I outlined how to easily create custom configuration code for accessing section of the App.config file. In some situation you may want to take things a little further, so let’s now look at using the IConfigurationSectionHandler to create the same configuration section.

To review, let’s look at the configuration section we’re going to create

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

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

So for this example, we’re not going to change this configuration and in fact we’ll keep the code which uses this configuration the same, so this will look like

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

The first thing we need to do is create the FiltersSection class which will implement IConfigurationSectionHandler. This requires that we implement the Create method. Now you could return the filter collection from this code instead of the FiltersSection, but I wanted to show how the two techniques would look, code-wise, for the same functionality. So in our Create method we’ll return the FiltersSection, as follows (the code below is the full implementation of the FilterSection, we’ll look at each bit of interest in a minute)

Note: I will not deal with error handling within this code so I can keep it to a minimum

public class FiltersSection : IConfigurationSectionHandler
{
   public FiltersSection()
   {
      Filters = new List<FilterType>();
   }

   public object Create(object parent, object configContext, XmlNode section)
   {
      var serializer = new XmlSerializer(typeof(FilterType));

      foreach (XmlNode node in section.ChildNodes)
      {
         if (node.Name == "Filters")
         {
            foreach (XmlNode filterNode in node.ChildNodes)
            {
               var reader = new XmlNodeReader(filterNode);
               Filters.Add((FilterType)serializer.Deserialize(reader));
            }
         }
      }
      return this;
   }

   public IList<FilterType> Filters { get; private set; }
}

So the obvious (boring bits) are we added a Filters property to the FiltersSection and instantiated it within the constructor, but the interesting stuff is within the Create method.

First off, as noted earlier, I wanted to mimic the behaviour of a previous post. So we return this