Click here to Skip to main content
15,884,176 members
Articles / Programming Languages / C#
Article

Configuration Management

Rate me:
Please Sign up or sign in to vote.
4.06/5 (11 votes)
27 Jul 2008CPOL3 min read 46K   514   40   4
This article shows how to store/handle configuration settings in a config file and backend database.

Introduction

It is important to be able to configure an application behavior at runtime. But it should be noted that there is a great difference between configuring an application that is deployed to a single machine and configuring one that is deployed to a distributed environment. The latter demands that all the participated machines must have the same configuration parameters at the same time. So, from the above perspective, we can separate two major kinds of configuration management. The first one is configuring an application via a configuration file. And, the second one is database server side configuration storage.

File configuration storage

One of the most propagated solutions is the usage of “*.config” files. The Microsoft .NET Framework has a special assembly “System.Configuration” that allows working with this. Also, there is an useful addition in the “Enterprise Library Configuration Application Block” which presents the FileConfigurationSource class for working with “*.config” files (one of the most interesting features is the ability to watch for file modifications and reload them on the spot).

I will introduce a solution that is based on custom System.Configuration.ConfigurationSection and Microsoft.Practices.EnterpriseLibrary. Common.Configuration.FileConfigurationSource. The main bonuses of using this kind of configuration management are:

  1. It gives a very simple usage to the developer;
  2. It watches “*.config” files and applies modifications without restarting the application;
  3. It can go independently from app.config/web.config files.

Implementation

First, we need to create a new class inheriting from System.Configuration.ConfigurationSection in order to define a custom configuration section. Then, we need to create a utility class that will manage the configuration file via the FileConfigurationSource class.

Here is the sample implementation:

C#
public class CustomSection : ConfigurationSection
{
    [ApplicationScopedSetting]
    [ConfigurationProperty("applicationName ", 
      DefaultValue = "My Application Default Name", IsRequired = true)]
    public String ApplicationName
    {
        get { return (String)this["applicationName"]; }
        set { this["applicationName "] = value; }
    }
}
public sealed class CustomSettings
{
    #region singletone
    private static CustomSettings _instance;
    private static readonly object _instanceSync = new object();
    private static CustomSettings Instance
    {
        get
        {
            if (CustomSettings._instance == null)
            {
                lock (CustomSettings._instanceSync)
                {
                    if (CustomSettings._instance == null)
                    {
                        CustomSettings._instance = new CustomSettings ();
                    }
                }
            }
            return CustomSettings._instance;
        }
    }
    #endregion singletone

    private FileConfigurationSource fileConfigurationSource;

    private CustomSettings()
    {
        string settingsPath = String.Concat(AppDomain.CurrentDomain.BaseDirectory, 
                                            "Custom.config");
        CustomSettings.fileConfigurationSource = 
                       new FileConfigurationSource(settingsPath);
    }

    public static CustomSettings Current
    {
    get {return CustomSettings.Instance.fileConfigurationSource.
                  GetSection("customSettings") as CustomSection;}
    }
}

Here is the sample "*.config" file source:

XML
<configuration>
    <configSections>
        <section 
        name="customSettings" 
        type="Sample.Config.CustomSection, Sample.Config, 
              Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
        allowDefinition="Everywhere" 
        allowExeDefinition="MachineToApplication" 
        restartOnExternalChanges="true" />
    </configSections>
    <customSettings
        applicationName="My Application"
    >
    </customSettings>
</configuration>

Here is the sample usage from the source code:

C#
string appName = CustomSettings.Current.ApplicationName;

As a conclusion, I would like to say that it is a good and quite simple solution. Also, it perfectly matches to standalone application usage.

Database server side configuration storage

Storing application settings in a configuration file is senseless for distributed applications (for example, a web application in a web farm). In that case, it is valuable to store settings in a single place. The most useful approach is storing settings in a backend database. But in this case, we need to solve the problem of serializing different types of settings into strings or binary. I would like to describe this problem in more detail.

All primitive types have static methods for parsing their values from strings. And, there is special class Convert which allows converting to string and back any type that implements the IConvertible interface. The only one rule that must be considered – it needs to store all the settings in invariant culture.

Sometimes, it is required to have more complex settings that are implemented as dedicated classes. Also, there is not much problem to serialize them into binary or XML content. (We need to mark the class with a Serializable attribute in order to serialize its instances into binary). Also, you may want to implement a custom serialization mechanism in order to avoid performance drawbacks of the default XML serialization functionality. By the way, it should be noted that caching brings perfect performance gain to this solution (please see my article: caching implementation receipt).

Afterwards, the usage of such settings management can look like:

C#
DateTime initialDate;
if (ServiceFacade.SettingsService.TryGetSetting<datetime />("INITIAL_DATE", 
                                                            out initialDate))
{
  // do something ...
}

Or, we can make it as simple as:

C#
DateTime initialDate = ServiceFacade.SettingsHelper.InitialDate;

Please refer to the attached source code for details.

License

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


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
AnswerError 9: The command "copy C:\Documents and Settings\...." exited with code 3. Pin
agorby28-Dec-08 22:59
agorby28-Dec-08 22:59 
Source: Solution Properties -> Build Events -> Pre-build event command line.

Please replace
copy $(ProjectDir)Custom.config $(ProjectDir)bin\debug\Custom.config

to
copy "$(ProjectDir)Custom.config" "$(ProjectDir)bin\debug\Custom.config"

Hmmm | :|
QuestionHow to Add-in for VS 2008 Pin
thangnt8428-Jul-08 15:32
professionalthangnt8428-Jul-08 15:32 
GeneralGood article, great quickstart Pin
evolved28-Jul-08 5:46
evolved28-Jul-08 5:46 
GeneralString not bool Pin
giammin27-Jul-08 22:45
giammin27-Jul-08 22:45 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.