IConfigurationSectionHandler Is Dead! Long Live IConfigurationSectionHandler!


I was tasked to create the configuration functionality of the architectural components for an SOA project that I previously worked on. I took as much time as I can in designing the XML thinking that it will be very easy to process it and churn it into a Configuration class by implementing the IConfigurationSectionHandler interface. And just when I started to develop it, I found out that the IConfigurationSectionHandler interface has been deprecated in .Net 2.0.

I’m the type of guy who is OC about this kind of stuff. And so I head forth to find out a solution. The page in MSDN for the interface says that.

In .NET Framework version 2.0 and above, you must instead derive from the ConfigurationSection class to implement the related configuration section handler.

Digging deeper, I learned that they have moved on to a more declarative way of processing configuration sections. So what used to be a series of xml manipulations is now a bunch of configuration classes decorated with the necessary attributes.

In this article, I will try to cover the necessary steps in creating a ConfigurationSection using the .Net 2.0 configuration classes.

The Mark-Up

When creating .Net configurations, I normally start with the xml markup to use. For the purpose of illustration, let’s just say I want to save a list of users and be able to read it at runtime.

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <configuration>

    3   <configSections>

    4     <section name="project-configuration"

    5             type="NewConfigurationSection.ProjectConfigurationSection,

    6                 NewConfigurationSection"/>

    7   </configSections>

    8   <project-configuration>

    9     <users>

   10       <add key="jakelite" firstname="jake" lastname="sta teresa" />

   11       <add key="pinoy" firstname="juan" lastname="dela cruz" />

   12       <add key="kano" firstname="uncle sam" lastname="lagmay" />

   13     </users>

   14   </project-configuration>

   15 </configuration>

The UserElement

The elements inside the users' node should map to a ConfigurationElement class. Each attribute in the configuration xml will map to a property decorated with a ConfigurationPropertyAttribute.

    1 internal class UserElement : ConfigurationElement

    2 {

    3     public UserElement()

    4     {           

    5     }

    6 

    7     public UserElement(string key)

    8     {

    9         Key = key;

   10     }

   11 

   12     [ConfigurationProperty("key", IsRequired = true, IsKey = true)]

   13     public string Key

   14     {

   15         get { return (string)(base["key"]); }

   16         set { base["key"] = value; }

   17     }

   18 

   19     [ConfigurationProperty("firstname", IsRequired = true)]

   20     public string Firstname

   21     {

   22         get { return (string)(base["firstname"]); }

   23         set { base["firstname"] = value; }

   24     }

   25 

   26     [ConfigurationProperty("lastname", IsRequired = true)]

   27     public string Lastname

   28     {

   29         get { return (string)(base["lastname"]); }

   30         set { base["lastname"] = value; }

   31     } 

   32 }

The UserElementCollection

The users' node should map to a ConfigurationElementCollection class. I find this to be the hardest part in doing this so I created a generic class called ConfigurationElementCollection<T>. The collection should be decorated with a ConfigurationCollectionAttribute specifying the type of ConfigurationElement is contains. 

    1 [ConfigurationCollection(typeof(UserElement),

    2     CollectionType = ConfigurationElementCollectionType.BasicMap)]

    3 internal sealed class UserElementCollection :

    4     ConfigurationElementCollection<UserElement>

    5 {

    6 }

The ConfigurationSection

As advised in the MSDN article, we should create a class that inherits from ConfigurationSection instead of the now deprecated IConfigurationSectionHandler interface. You will find the configuration section class below.

    1 public sealed class ProjectConfigurationSection :

    2     ConfigurationSection

    3 {

    4     [ConfigurationProperty("users",

    5         IsDefaultCollection = true, IsRequired = true)]

    6     internal UserElementCollection Users

    7     {

    8         get { return (UserElementCollection)this["users"]; }

    9     }

   10 }

Retrieving The Users

To retrieve the users contained in the configuration, you will have to open the configuration, then locate the configuration section of the target type. Then you can cast it to the target type and use the class in a strongly typed manner. This allows you to access the child nodes as properties.

    1 Configuration configuration =

    2     ConfigurationManager.OpenExeConfiguration(

    3         ConfigurationUserLevel.None);

    4 ProjectConfigurationSection configurationSection = null;

    5 ConfigurationSectionCollection sections = configuration.Sections;

    6 foreach (ConfigurationSection section in sections)

    7 {

    8     if (section is ProjectConfigurationSection)

    9     {

   10         configurationSection = section

   11             as ProjectConfigurationSection;

   12         break;

   13     }

   14 }

   15 

   16 if (configurationSection != null)

   17 {

   18     Console.WriteLine("Configured Users");

   19     foreach (UserElement user in configurationSection.Users)

   20     {

   21         Console.WriteLine("User {0}: {1} {2}",

   22             user.Key,

   23             user.Firstname,

   24             user.Lastname);   

   25     }

   26     Console.ReadKey(false);

   27 }

Final Words

In this article we looked at the new way of accessing .Net configuration. This new approach offers a more declarative/OO way of accessing configuration.

However, the sheer verbosity of the new programming model is quite tedious. Add to that the lack of proper samples in the documentation; particularly when implementing ConfigurationElementCollections.

In the end, you will have to choose the new approach if you want to future proof your application configuration strategy. But as for me, I’d trade it anytime to get back IConfigurationSectionHandler.

Code for the samples can be found here.

Filed under: , ,

Comments

# Erryl said:

Waah!!!! And I was just thinking of doing the configuration manager thing...

Sunday, January 11, 2009 5:08 PM
# jakelite said:

This is the third installment to my series of posts about threading patterns. Today we will look into

Tuesday, February 03, 2009 5:54 AM
# jakelite said:

I was working on a MsScriptControl based ETL project. One of its requirements is to be able to use vbscript

Sunday, March 22, 2009 6:56 AM