Jan Schreuder on .Net

.Net code samples, experiences, observations

View my professional profile on LinkedIn

Recent Posts

Tags

News

  • Inappropriate comments will be deleted at my discretion.

    The information and code samples in this weblog is provided "AS IS" without warranty of any kind, either expressed or implied, including but not limited to the merchantability and/or fitness for a particular purpose.

Community

Email Notifications

Tool suppliers

Tools

General

Microsoft

Favorite blogs

Archives

Using section handlers to group settings in the configuration file.

Introduction

It is common practice to store application settings in the app.config (or web.config) configuration files. The larger the application, the more settings you will tend to have. However, as the number of settings grow for an application, so does the need to bring more structure in these configuration files. Let's look at a small configuration file:

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

<configuration>

<appSettings>

<add key="ConnectionString" value="data source=.;initial catalog=NorthWind;integrated security=SSPI"/>

<add key="ImportDirectory" value="C:\Import\Inbox"/>

<add key="ProcessedDirectory" value="C:\Import\Processed"/>

<add key="RejectedDirectory" value="C:\Import\Rejected"/>

</appSettings>

</configuration>

Because of the small number of settings here, the readability is pretty good. But it might be useful if you could structure these settings into two groups: Database and Locations.

The .Net framework offers a few options in the form of SectionHandlers that reside in the System.Configuration namespace that will allow you to create these groups. This article describes how to use these section to introduce custom sections. A zip file containing a demonstration project can be downloaded from this location.

NameValueSectionHandler

The NameValueSectionHandler is the handler used by most .Net developers, without even knowing it. This section handler allows you to add settings to the configuration file in the form of key value pairs. The example above shows you just that.

But as said, the idea is to group different types of settings into appropriate sections. To do this  you first need to change the configuration file. First step is to define the sections in the configuration file that we want to use. In the configuration file, add a new section with the name configSections. In this group you can define the sections and the handlers that will be used to handle these settings. Here is an example that uses the NameValueSectionHandler:

<configuration>

<configSections>

<section name="Database" type="System.Configuration.NameValueSectionHandler" />

<section name="Locations" type="System.Configuration.NameValueSectionHandler" />

</configSections>

</configuration>

Now that the sections have been defined, it is time to place the settings into the appropriate groups. The completed configuration file now looks like this:

<configuration>

<configSections>

<section name="Database" type="System.Configuration.NameValueSectionHandler" />

<section name="Locations" type="System.Configuration.NameValueSectionHandler" />

</configSections>

<Database>

<add key="ConnectionString" value="data source=.;initial catalog=NorthWind;integrated security=SSPI"/>

</Database>

<Locations>

<add key="ImportDirectory" value="C:\Import\Inbox"/>

<add key="ProcessedDirectory" value="C:\Import\Processed"/>

<add key="RejectedDirectory" value="C:\Import\Rejected"/>

</Locations>

</configuration>

The NameValueSectionHandler returns a specialised NameValueCollection which contains all entries after you call ConfigurationSettings.GetConfig(). Reading this information from the configuration file can be accomplished in the following manner:

private void ReadSettings()
{
    NameValueCollection db = (NameValueCollection)ConfigurationSettings.GetConfig("Database");
 
    labelConnection2.Text = db["ConnectionString"];
 
    NameValueCollection loc = (NameValueCollection)ConfigurationSettings.GetConfig("Locations");
 
    labelImport2.Text = loc["ImportDirectory"];
    labelProcessed2.Text = loc["ProcessedDirectory"];
    labelRejected2.Text = loc["RejectedDirectory"];
}

As you can see, this is a very simple way of grouping settings into appropriate sections. This example only contains a few settings, so grouping the settings is not something you would normally do. But with larger amounts of settings, grouping of settings becomes really useful.

DictionarySectionHandler

The DictionarySectionHandler is similar to the NameValueSectionHandler. The difference is that this handler returns a HashTable rather than the specialised NameValueCollection. HashTables are faster than the NameValueCollection when you have large amounts of settings.

You can use the DictionarySectionHandler in the same way as the NameValueSectionHandler. In the configuration file, you will need to use DictionarySectionHandler as the type for the section. Defining values for this handler type is identical to the NameValueSectionHandler. The following code sample shows how you can access the settings when you use the DictionarySectionHandler:

private void ReadSettings()
{
    Hashtable db = (Hashtable)ConfigurationSettings.GetConfig("Database");
 
    labelConnection2.Text = db["ConnectionString"].ToString();
}

As said, this is pretty similar to the NameValueSectionHandler with the difference of using a HashTable instead of the NameValueCollection.

SingleTagSectionHandler

The third section handler is the SingleTagSectionHandler. When you choose to use this handler, you no longer define each section as a key value pair. You're actually creating your own custom tags with the values you want to use. Let's take the configuration file used for the NameValueSectionHandler and change the type for section Locations to SingleTagSectionHandler. The configSections part of the file will then look like this:

<configuration>

<configSections>

<section name="Database" type="System.Configuration.NameValueSectionHandler" />

<section name="Locations" type="System.Configuration.SingleTagSectionHandler" />

</configSections>

</configuration>

Now that the section type has been changed, you can create your own Locations tag in the configuration file in the following manner:

<Locations

ImportDirectory="C:\Import\Inbox"

ProcessedDirectory ="C:\Import\Processed"

RejectedDirectory ="C:\Import\Rejected"

/>

You see that you can define your values in a really easy manner. The code to read the information for the custom Locations section looks like this:

private void ReadLocations()
{
    Hashtable loc = (Hashtable)ConfigurationSettings.GetConfig("Locations"); 
 
    labelImport2.Text = loc["ImportDirectory"].ToString();
    labelProcessed2.Text = loc["ProcessedDirectory"].ToString();
    labelRejected2.Text = loc["RejectedDirectory"].ToString();
}

Conclusion

Grouping your settings in logical sections makes sense. It will make it easier to maintain your configuration file and a lot more logical. Once you've introduced sections, you can make sure that settings that are used in the same context are located in the same location. I've seen a lot of applications where new settings are simply added to the list. It is then almost impossible to maintain.

The .Net framework offers you several options to group settings into logical groups. It is also very easy to use. More information on these section handlers can be found on MSDN by following these links:

Feel free to download the demonstration project attached to this article and see for yourself how these handlers work.

Comments

Sandra L. said:

Really helpful.

# October 5, 2008 6:21 PM

Kuljit said:

Very useful.. exactly what I was looking for.

# April 5, 2009 11:00 AM

Binoj Antony said:

How about doing this with an additional SectionGroup then Section. How will this be implemented

# October 26, 2009 10:27 AM

kiquenet said:

I cannot download zip file containing a demonstration project , any solution ??

# October 25, 2010 3:52 PM

Prashant said:

Many thanks!!!

# December 16, 2011 1:56 PM

Serghei Burtsev said:

Thanks! Very helpful!

# May 4, 2012 7:55 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Please add 2 and 6 and type the answer here: