C# : Custom configuration section

February 12, 2011 by C#  

Generally when we develop applications using .NET, we use our app/web.config as a place where we expose certain settings to our application(s) (its even possible to encrypt it for those who dare or feel the higher calling to use it to store sensitive information).

Your config file will likely look something like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="1" value="a" />
    <add key="2" value="b" />
    <add key="3" value="c" />
  </appSettings>
</configuration>

Next we'll wack a reference to the system.configuration assembly into our application, which will allow us to access our settings via the ConfigurationManager - like seen in the following image.



Now we can always simply use the general appSettings section to store some rudimentary settings, but what if we wish to create a separate appSettings section specific to our company for example?

In the following snippet we do exactly that, we add a new section called "Company.appSettings", using one of the default section handlers, observe:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="Company.appSettings" type="System.Configuration.NameValueFileSectionHandler" />
  </configSections>
  <Company.appSettings>
    <add key="1" value="a" />
    <add key="2" value="b" />
    <add key="3" value="c" />
  </Company.appSettings>
  <appSettings />
</configuration>

Programmatically we'll access the newly added section like this:

NameValueCollection settings = ConfigurationManager.GetSection("Company.appSettings") as NameValueCollection;
if (settings != null)
{
	foreach (string key in settings)
	{
		Console.WriteLine("{0} : {1}", key, settings[key]);
	}
}

An alternative to using notation like Company.appSettings is that you can instead separate your custom sections using the sectionGroup node like so:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="Company">
      <section name="appSettings" type="System.Configuration.NameValueFileSectionHandler" />
    </sectionGroup>
  </configSections>
  <Company>
    <appSettings>
      <add key="1" value="a" />
      <add key="2" value="b" />
      <add key="3" value="c" />
    </appSettings>
  </Company>
  <appSettings />
</configuration>

Accessing the settings from code will look something like this:

NameValueCollection settings = ConfigurationManager.GetSection("Company/appSettings") as NameValueCollection;

This is obviously not the limit to the customization possibilities - you might have seen/used the following settings in your config file when setting up .NET for sending mail:
<system.net>
  <mailSettings>
    <smtp>
      <network host="smtp.somehost.net" />
    </smtp>
  </mailSettings>
</system.net>

It is quite easy to create our own custom section similar to what we see in the preceding snippet.

The following snippet will give you a quick idea on how to create your own custom section, note inherited classes ConfigurationSection and ConfigurationElement.

using System;
using System.Configuration;

namespace Sections
{
    public class XSection : ConfigurationSection
    {
        [ConfigurationProperty("x", DefaultValue = false, IsRequired = false)]
        public Boolean X
        {
            get
            {
                return (Boolean)this["x"];
            }
            set
            {
                this["x"] = value;
            }
        }

        [ConfigurationProperty("y")]
        public YElement Y
        {
            get
            {
                return (YElement)this["y"];
            }
            set
            {
                this["y"] = value;
            }
        }
    }

    public class YElement : ConfigurationElement
    {
        [ConfigurationProperty("y1", DefaultValue = "value", IsRequired = false)]
        public String Y1
        {
            get
            {
                return (String)this["y1"];
            }
            set
            {
                this["y1"] = value;
            }
        }

        [ConfigurationProperty("y2", IsRequired = true)]
        public Int32 Y2
        {
            get
            {
                return (Int32)this["y2"];
            }
            set
            {
                this["y2"] = value;
            }
        }
    }
}

The custom section will look something like this in your config file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="XSection" type="Sections.XSection, ConsoleApplication1"  allowLocation="true"
        allowDefinition="Everywhere" />
  </configSections>
  <XSection x="true">
    <y y1="test1" y2="10" />
  </XSection>
</configuration>

In order to access the custom node from code, you need to do the following:

Sections.XSection xsection = ConfigurationManager.GetSection("XSection") as Sections.XSection;
if (xsection != null)
{
    Console.WriteLine(xsection.X);
    Console.WriteLine(xsection.Y.Y1);
    Console.WriteLine(xsection.Y.Y2);
}

There is a lot of other options also available, like the configurationcollection attribute - which allows us to add collections as settings to our config files - be sure to read the additional reading at the bottom of the page.

Additional Reading:
http://msdn.microsoft.com/en-us/library/2tw134k3.aspx
http://msdn.microsoft.com/en-us/library/system.configuration.configurationcollectionattribute.aspx


Leave a Comment


Re: Useful but.. February 20, 2014 by Christoff Truter

Thanks Rex, wish you elaborated on what you find so vague? This is a very basic concept though?

August 19, 2013 by Rex Farris

Useful information, but presented vaguely and............in a disorganized way.....too many x's and y's and not enough indication how it fits together.

RE: Cinchoo March 17, 2012 by Christoff Truter

Thank you for taking the time to introduce me to the Cinchoo Framework, I will definitely have a look at it.

March 17, 2012 by Anonymous

There is better way of managing Configuration in .NET using Cinchoo Framework. Just define a configuration class as below #region NameSpaces using System; using Cinchoo.Core.Configuration; #endregion NameSpaces [ChoConfigurationSection("sample")] public class SampleConfigSection : ChoConfigurableObject { #region Instance Data Members (Public) [ChoPropertyInfo("name", DefaultValue="Mark")] public string Name; [ChoPropertyInfo("message", DefaultValue="Hello World!")] public string Message; #endregion } Then instantiate it and use it as below, class Program { static void Main(string[] args) { SampleConfigSection sampleConfigSection = new SampleConfigSection(); Console.WriteLine(sampleConfigSection.ToString()); //Shutdown the framework to stop the background services...otherwise the application will not terminate ChoFramework.Shutdown(); } } Corresponding entries will be created in applicationexename.xml file as below <?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="sample" type="Cinchoo.Core.Configuration.Handlers.ChoNameValueSectionHandler, Cinchoo.Core" /> </configSections> <cinchoo> <sample> <add key="name" value="Mark" /> <add key="message" value="Hello World!" /> </sample> </configuration> For more information, please visit http://www.cinchoo.com

Thanks for sharing! September 16, 2011 by Kiran

Hi Chris, Thanks for posting the detailed explanation. Helped a lot getting going on exploring the web config file and creating my own custom config section. Much appreciated!

thanks March 14, 2011 by Fernando Pires

Helped me a lot..great posting