Click here to Skip to main content
Click here to Skip to main content

Custom Configuration Sections in .NET

By , 28 Feb 2011
 

Introduction

Inevitably, .NET developers will need to store application configuration data. Most often, developers choose to store this data in an XML Configuration File (.config). There are many different sections of this file that allow for the configuration of different areas of the application. One of these sections is the appSettings section. This section is a series of name-value pairs that can be used to add custom configuration data for an application. Over time, this section tends to become messy as an applications' functionality grows and complexity expands. In this article, we're going to look at how we can build custom configuration sections that will allow us to simplify our applications configuration data.

Using the Code

Here’s an example of an appSettings configuration section:

<appsettings>
    <!--Misc Settings-->
    <add key="StandardHandlingFee" value="4.95" />
    <add key="PageSize" value="5" />

     ...
</appsettings>

Over time, the number of configuration items tends to grow and managing them can become confusing. What you end up with is a seemingly endless list of key value pairs that are difficult to manage. Additionally, the code required to access their values can start to get tedious.

using System;
using System.Configuration;

namespace Before
{
    class Program
    {
        static void Main(string[] args)
        {
            // Load Misc Settings
            decimal standardHandlingFee =
            Convert.ToDecimal(ConfigurationManager.AppSettings
            ["StandardHandlingFee"]);
            int pageSize = Convert.ToInt32
            (ConfigurationManager.AppSettings["PageSize"]);

            // ... do work ...
        }
    }
}

.NET has given the developers the ability to simplify this process by creating custom configuration sections. These custom configuration sections can help turn unstructured, untyped data into strongly-typed, straightforward elements. Basically, taking the almost meaningless key-value pairs and turning them into something more meaningful.

There are 3 pieces that makeup the custom configuration; a class that inherits from System.Configuration.ConfigurationSection; “registering” your configuration class in the configSections of your configuration file; and the XML configuration itself.

First is the class that handles how we access the configuration data.

using System;
using System.Configuration;

namespace After.Configuration
{
    public class TestAppConfigProviderSection : ConfigurationSection
    {
        public static readonly TestAppConfigProviderSection Current =
        (TestAppConfigProviderSection)ConfigurationManager.GetSection
	("testAppConfigProvider");

        [ConfigurationProperty("StandardHandlingFee", DefaultValue = "4.95")]
        public decimal StandardHandlingFee
        {
            get { return (decimal)base["StandardHandlingFee"]; }
            set { base["StandardHandlingFee"] = value; }
        }

        [ConfigurationProperty("PageSize", DefaultValue = "10")]
        public int PageSize
        {
            get { return (int)base["PageSize"]; }
            set { base["PageSize"] = value; }
        }
    }
}

This class is pretty straightforward, but there are some key things to take note of. First, the main ConfigurationSection class must derive from the System.Configuration.ConfigurationSection class.

Also, within the TestAppConfigProviderSection class, I use a singleton style approach with the Current member. This helps make accessing the properties within the configuration section easy.

The configuration properties that the class is exposing should use the ConfigurationProperty attribute. The name that gets passed in this attribute should match the attribute name in the configuration file.

“Registering” our configuration section is done by adding a section in the configSections of the application’s .config file. The XML configuration is restructured to match how it is defined in our class. Here’s the new .config file after being refactored.

<configuration>
  <configSections>
    <section name="testAppConfigProvider" 
	type="After.Configuration.TestAppConfigProviderSection, After"/>
  </configSections>
  <testAppConfigProvider StandardHandlingFee="4.95" PageSize="10" />
</configuration>

Here’s our example code again, but using the custom configuration sections:

using System;
using After.Configuration;

namespace After
{
    class Program
    {
        static void Main(string[] args)
        {
            // Load Misc Settings
            decimal standardHandlingFee =
            TestAppConfigProviderSection.Current.StandardHandlingFee;
            int pageSize = TestAppConfigProviderSection.Current.PageSize;

            // ... do work ...
        }
    }
}

It is also possible to load the custom configuration sections from an external file like so:

<configuration>
  <configSections>
    <section name="testAppConfigProvider"
    type="After.Configuration.TestAppConfigProviderSection, After"/>

  </configSections>
  <testAppConfigProvider configSource="testApp.config" />
</configuration>

Where testApp.config looks like this:

<testAppConfigProvider StandardHandlingFee="4.95" PageSize="10" />

One important note on using this method, you must make sure that you change the Copy to Output Directory property on the new .config file to either ‘Copy if newer’ or ‘Copy always’. Otherwise, the file won’t get copied to the projects bin directory and the ConfigurationManager won’t be able to load the file.

The benefits of using a custom configuration section handler are significant. Using the handler code is pretty straightforward and gives you less clutter in the appSettings as well as strong typing of your configuration elements.

History

  • 28th February, 2011: Initial post
  • 28th February, 2011: Article updated

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Pete Mourfield
Software Developer (Senior)
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionHow to deal with dll in sub folder? [modified]memberPaddington6 Jan '12 - 21:33 
Thanks Pete for this instructive article!
 
With your instructions, it was easy to create a custom Section for my.dll in the main app.config. Everything worked well until I moved my.dll to a plugin folder. Although I could still create a section, I was never able to load it again, since it apparently required to have access to my.dll in the main application's directory (I received a ConfigurationErrorsException, telling me that it could not find my.dll).
Any idea how to get around this?
 
EDITED:
Never mind the question. I found a simple way to get around this. Simply use the Probing [^] tag as part of your app.config and reference the Plugin folder. According to MSDN, it "Specifies application base subdirectories for the common language runtime to search when loading assemblies."
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="Plugin"/>
    </assemblyBinding>
  </runtime>
</configuration>
Author of SubtitleCreator


modified 7 Jan '12 - 6:55.

GeneralMy vote of 5memberMonjurul Habib2 Apr '11 - 10:44 
nice one.
QuestionIs there something new here ?memberrmiguel9 Mar '11 - 3:19 
That's just the basic of the basic as it exists since the release of .NET 2, some years ago.
GeneralDiving furthermemberJohn Whitmire8 Mar '11 - 7:16 
You can go a little deeper into this topic by looking at Custom Configuration Sections for Lazy Coders[^], and still deeper by reading the comments there, particularly this one[^].
GeneralMy vote of 5memberManfred R. Bihy28 Feb '11 - 23:36 
Nice article! I think this is something every .NET developer should know about.
GeneralMy vote of 5memberTieske828 Feb '11 - 21:40 
Boink.... the sound of this one dropping into my toolbox.
Generalnice articlememberCIDev28 Feb '11 - 3:57 
A nice little article on a topic with which not enough programmers are familar.
A minor detail, in the first paragraph you have the sentence "One of these sections is the section."
I think you meant "One of these sections is the appSettings section.". Smile | :)
Just because the code works, it doesn't mean that it is good code.

GeneralMy vote of 5memberPaulo Zemek28 Feb '11 - 3:41 
I don't think this is a full article, but I liked. I really didn't I could make configuration files type-safe by "default".
GeneralRe: My vote of 5memberPete Mourfield28 Feb '11 - 3:49 
Hey thanks! You mention that you don't think this is a full article. What can I do to make it better?

GeneralRe: My vote of 5memberPaulo Zemek28 Feb '11 - 3:51 
To be honest, I don't know. I think it is too small for an article, but I honestly don't know what else could be done.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 28 Feb 2011
Article Copyright 2011 by Pete Mourfield
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid