Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Custom AppSettings

0.00/5 (No votes)
29 Nov 2005 1  
Another article on AppSettings.

Introduction

There are a lot of articles that talk about the App.config file for .NET applications, be them Console applications, WinForms applications or Services, not only in CodeProject but all over the internet.

They might all look a like; but the bottom line is that none of them are the same. That's why I'm sure this article won't be the same as all of the other ones you have found and read. Who knows it might help you in some way, or even better you might get some ideas and improve it.

That was my case, I was looking for a custom, general way that I could use to read my App.config, but none of the articles I read convinced me nor solved the need I had at the time but they sure gave me good ideas of what I wanted in my own implementation.

Other people's ideas

There are two main ideas I took from other people in this open source site (of course I'm talking about CodeProject).

Paul Haley wrote in his "Enhanced AppSettings Configuration Handler" article that there are times when you need to try out your application in different environments with different configurations, and editing or commenting code for this matter can be rather annoying. Besides, the App.config is a file where all the configuration should be. (He explains more disadvantages.)

Anyway, his approach is a little more hostname oriented, and if you want to change this, you must inherit from his class and do some other stuff I didn't bother to read.

Diego Mijelshon has an article on "How to make AppSettings work with multiple values for a key". Now, you must agree with me that this is also a good idea. He states clearly that .NET has this serious flaw and he kind of explains the reason. He also shows how to get multiple values for a key, but I think he complicated it a little bit using reflection (not that reflection is hard) for reasons I am not aware of.

I must point out that there is nothing wrong with both articles, they work fine, but my needs were different, so I thought these would be too complicated and I was correct.

Background

It is recommended, of course, to know about appSettings, the System.Configuration.ConfigurationSettings class, the App.config file, and XML in which this file is coded. These subjects are rather easy and I guess most [.NET] programmers must know or at least must have heard about them, right?

OK, with this stated... let's get it on!

Main idea

As you might have read, you can get simple values inside the App.config using ConfigurationSettings.AppSettings[...] or you can create and read custom sections using the ConfigurationSettings.GetConfig(string sectionName) method, but if you want to read your config file by yourself, you have to create a class that implements the IConfigurationSectionHandler interface and this is very easy to do, for example:

public class AppSettingHandler : IConfigurationSectionHandler

Doing this forces you to implement a method inside your class, the Create(...) method, which basically gives you the whole App.config file already in an XmlNode called section. Inside the method, you can read the values in any way you want to.

public virtual object Create(object parent, object configContext, XmlNode section)

Using and getting the code right

Now, for your main code to automatically call the Create(...) method you just implemented, you have to do the following:

First, you must have a valid and correct App.config XML file associated to your application. Inside it you must have something like this, so that you can use the code I'm providing:

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

    <configSections>
        <remove name="appSettings"/>
        <section name="appSettings" 
                type="BellAppSetting.AppSettingHandler, BellAppSetting" />
    </configSections>

    <appSettings>
        <!-- CONFIGURATION GOES HERE-->     
    </appSettings>
    
</configuration>

Before I continue, I would like to point out that it is not necessary to remove the appSettings section, this is just if you want to put your configuration inside the <appSettings> tag. You can have something like this instead:

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

    <configSections>
        <section name="TheNameIwant" 
                  type="BellAppSetting.AppSettingHandler, BellAppSetting" />
    </configSections>
    
    <TheNameIwant>
        <!-- CONFIGURATION GOES HERE-->
    </TheNameIwant>

</configuration>

Second, you have to call the following line from your main code:

ArrayList nvc;
nvc = (ArrayList)ConfigurationSettings.GetConfig("appSettings");

if you have used <remove name="appSettings"/> in the App.config file or:

ArrayList nvc;
nvc = (ArrayList)ConfigurationSettings.GetConfig("TheNameIwant");

if you have used <section name="TheNameIwant" in the App.config file.

The example you get

As you can see from the line called from the code, you receive in return an ArrayList. Its structure will be shown in the following example. If you want further details, don't hesitate to download the source code.

Say your App.config looks something like this:

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

    <configSections>
        <remove name="appSettings"/>
        <section name="appSettings" 
                    type="BellAppSetting.AppSettingHandler, BellAppSetting" />
    </configSections>
    
    <appSettings>

          <Configs use="true"> 
            <add key="ClientConfig" use="true" />
            <add key="ServerConfig" use="true"/> 
            <add key="OtherValue3" use="false"/> 
          </Configs>

          <Configs use="true"> 
            <add key="ClientConfig" use="true" />
            <add key="ServerConfig" use="true"/> 
            <add key="OtherValue3" use="true"/> 
            <add key="OtherValue4" use="true"/> 
          </Configs>
        
          <ClientConfig use="true">
            <add key="Address2Connect" value="192.168.1.107"/> 
            <add key="Port2Connect" value="2000"/> 
            <add key="Log2File" value="Logging.txt"/>          
          </ClientConfig>
          
          <ClientConfig use="true">
            <add key="Address2Connect" value="192.168.1.105"/> 
            <add key="Port2Connect" value="2000"/> 
          </ClientConfig>
              
          <ServerConfig use="true">
            <add key="PortListenerName" value="2002"/> 
            <add key="Port2Listen" value="2002"/> 
            <add key="PortLisFile2Log" value="Logging.txt"/>
          </ServerConfig>
          
          <ServerConfig use="false">
              <add key="PortListenerName" value="2004"/> 
            <add key="Port2Listen" value="2004"/> 
            <add key="PortLisFile2Log" value="Logging.txt"/>
            <add key="PortLisLogAll2File" value="false"/>
            <add key="GossipSockets" value ="false"/>
            <add key="SocketLogAll2IndependantFile" value="false"/>
         </ServerConfig>
         
          <OtherValue4 use="true"> 
            <add key="CheckConnections" value="false"/> 
            <add key="NotifyUserWhenDone" value="true"/> 
            <add key="OtherConfigValue" value="1"/> 
            <add key="OtherConfigValue" value="2"/> 
          </OtherValue4>
         
    </appSettings>
    
</configuration>

If you process this App.config with the sample project, you'll get something like this:

Some last notes

  • The <Configs> node serves as the section collection.
  • You can put as many <Configs> nodes as you want.
  • You can put as many element nodes as you want.
  • You can see all nodes have a use attribute that can take true or false, telling the code if it will be skipped or not.
  • A Hashtable is used for each element node, so if you repeat them they will be ignored.
  • A DictionaryEntry is used to allow multiple values for the same key.

Points of Interest

Doing your own implementation of a AppSettings reader is not as hard as you might think. Of course this depends on how much you want to do, but reading the XmlNode was pretty easy and straightforward. You receive an ArrayList with Hashtables plus ArrayLists plus DictionaryEntries. I know it might sound complicated but searching within is easy and can be done with foreachs, just as it's shown in the sample project.

If you bother to look at the code, it looks pretty easy, don't you think? This worked for me, and it might work for you too, so take a look.

In resume, this helps you use multiple configurations for your projects by just turning them ON or OFF by changing the use attribute values and you can also insert multiple values for the same key.

Enjoy! Don't forget, any comments, criticisms, questions or anything are always welcomed!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here