Click here to Skip to main content
13,797,882 members
Click here to Skip to main content
Add your own
alternative version


31 bookmarked
Posted 5 Jan 2012
Licenced CPOL

Simple and flexible way to access and store configuration settings

, 6 Jan 2012
Rate this:
Please Sign up or sign in to vote.
An easy way to manage application configuration with a wide range of options for storage.


Recently I have been working on a task that required a lot of flexibility in storing and accessing configuration settings. I have searched the web and found plenty of solutions and examples but none of them really satisfied my requirements. This forced me to give up the search and to consider writing my own version. Once I got to the point that it appeared to be working, I decided to share it in case someone might find it more useful than the rest of the options out there.


In order to finish the task, I had to make sure the following conditions were met in order to make it useful:

  1. User should be able to easily change or choose how and where configuration data is stored without affecting the configurable objects.
  2. Accessing and storing configuration should be very simple and transparent to the user but at the same time reliable.
  3. Types of any of the child objects are not known to the process that initiates loading of configuration and child objects are created depending on specific configurations.

A potential solution came to mind when I was working on a web project and used View State to store some values between page post backs. It reminded me that strings can represent any data including binary. They are relatively easy to use and can be stored pretty much anywhere - XML file, database, or even binary file. And just like we operate with strings in XML, we can access and store data as strings and convert it to appropriate data types when loading.

In order to be able to manage complex configurations, I had to come up with two concepts which we’ll call context and value. Context is simply a container that holds a collection of other contexts and values, and values are just simple string values. The loading and saving is done using two methods that perform reading and writing configuration to the appropriate context which is similar to the IXmlSerializable interface.

Using the code

You will need to implement the IConfigurationElement interface so that class configuration can be saved and loaded. The interface is similar to the IXmlSerializable interface and includes two methods: ReadConfiguration and WriteConfiguration. As their names suggest, one is used to read configuration and the other to write.

public interface IConfigurationElement
    void ReadConfiguration(IConfigurationContext context);
    void WriteConfiguration(IConfigurationContext context);

Since we are dealing with strings only, we can use indexers to load and save a value. It will be the user’s responsibility to convert a string to the appropriate data type when reading, and back when writing. For example:

// writing
context["DateOfBirth"] = DateOfBirth.ToShortDateString();

// reading
DateTime dt;
DateTime.Parse(context["DateOfBirth"], out dt);

Question now, what do we do if we want to save a subset of configuration values? In this case, you need to obtain a context object from the current context by ether creating a new one or getting an existing one. For this, IConfigurationContext provides three methods: Get, GetAll, and Create. The Get method accepts a string parameter that specifies the name of the parameter and returns a list of contexts. GetAll will return all contexts associated with the current context and you can access the context name by using the property Name. Accordingly, the Create method will create a new context with the provided name.

Here is the full interface definition:

public interface IConfigurationContext
        IEnumerable<IConfigurationContext> Get(string contextName);
        IEnumerable<IConfigurationContext> GetAll();
        string this[string name] { get; set; }
        string Name { get; }
        IConfigurationContext Create(string contextName);

Below is an example of accessing and storing a person's name (FirstName and LastName) and postal address (MailingAddress). The example below does not include the implementation of the PostalAddress class but it is available in the attached source code together with other validation logic not shown here.

public class Person : IConfigurationElement
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public PostalAddress MailingAddress { get; set; }

    public void WriteConfiguration(IConfigurationContext context)
        context["FirstName"] = FirstName;
        context["LastName"] = LastName; 
        var ctx = context.CreateContext("MailingAddress");

    public void ReadConfiguration(IConfigurationContext context)
        FirstName = context["FirstName"];
        LastName = context["LastName"];
        var ctx = context.GetContext("MailingAddress");

Now let’s look at how this can be used. For this demonstration, I created a working implementation of IConfigurationContext that uses XmlNode to store configurations. So below is an example that should be simple enough to understand.

// loading
static void Main()
    var xmlDoc = new XmlDocument();
    var context = new XmlConfigurationContext(xmlDoc.DocumentElement);
    var person = new Person();

// saving
static void Main()
    var xmlDoc = new XmlDocument();
    var context = new XmlConfigurationContext(xmlDoc, "Person");

And below is an example of the created configuration file:

<Context Name="Person">
 <Value Name="FirstName">FirstName</Value>
 <Value Name="LastName">LastName</Value>
 <Context Name="MailingAddress">
  <Value Name="Street1">Street1</Value>
  <Value Name="Street2">Street2</Value>
  <Value Name="City">City</Value>
  <Value Name="State">State</Value>
  <Value Name="Zip">Zip</Value>

So let’s go back and review my requirements.

  1. User should be able to easily change or choose how and where configuration data is stored without affecting the configurable objects. We accomplished that by simply providing different implementations of IConfigurationContext. So instead of XmlConfigurationContext, we can easily create DatabaseConfigurationContext or WebServiceContext or other variations.
  2. Accessing and storing configuration should be very simple and transparent to the user but at the same time reliable. Accessing settings is straightforward and simple using the simple indexer.
  3. Types of any of the child objects are not known to the process that initiates the loading of the configuration. When loading Person, we do not know what settings it will save nor do we care, we simply provide the context where to save or find the needed values.


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


About the Author

Aleksey Shurtygin
CEO i3 Quest Inc
United States United States
No Biography provided
Group type: Organisation (No members)

You may also be interested in...

Comments and Discussions

GeneralGood article Pin
Sampath Sridhar3-Dec-14 2:51
memberSampath Sridhar3-Dec-14 2:51 
QuestionSetup for lists? Pin
RoketSauce31-Jan-12 6:29
memberRoketSauce31-Jan-12 6:29 
AnswerRe: Setup for lists? Pin
Aleksey Shurtygin31-Jan-12 8:42
groupAleksey Shurtygin31-Jan-12 8:42 
GeneralRe: Setup for lists? Pin
RoketSauce1-Feb-12 4:17
memberRoketSauce1-Feb-12 4:17 
GeneralMy vote of 2 Pin
Corvus Corax18-Jan-12 19:07
memberCorvus Corax18-Jan-12 19:07 
GeneralMy vote of 1 Pin
Thornik9-Jan-12 22:25
memberThornik9-Jan-12 22:25 
GeneralRe: My vote of 1 Pin
HaBiX9-Jan-12 23:25
memberHaBiX9-Jan-12 23:25 
GeneralRe: My vote of 1 Pin
Thornik9-Jan-12 23:33
memberThornik9-Jan-12 23:33 
GeneralRe: My vote of 1 Pin
HaBiX10-Jan-12 0:59
memberHaBiX10-Jan-12 0:59 
GeneralRe: My vote of 1 Pin
Aleksey Shurtygin10-Jan-12 8:23
groupAleksey Shurtygin10-Jan-12 8:23 
GeneralRe: My vote of 1 Pin
Aleksey Shurtygin10-Jan-12 9:20
groupAleksey Shurtygin10-Jan-12 9:20 
Questionnice Pin
shaheen_mix6-Jan-12 20:20
membershaheen_mix6-Jan-12 20:20 
GeneralMy vote of 1 Pin
Joe Sonderegger6-Jan-12 5:28
memberJoe Sonderegger6-Jan-12 5:28 
GeneralRe: My vote of 1 Pin
Aleksey Shurtygin6-Jan-12 7:29
groupAleksey Shurtygin6-Jan-12 7:29 
GeneralMy vote of 4 Pin
Yeurl_20076-Jan-12 0:39
memberYeurl_20076-Jan-12 0:39 
GeneralRe: My vote of 4 Pin
Aleksey Shurtygin6-Jan-12 3:42
groupAleksey Shurtygin6-Jan-12 3:42 
GeneralMy vote of 5 Pin
Tom Clement5-Jan-12 8:07
mentorTom Clement5-Jan-12 8:07 

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.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web03 | 2.8.181207.3 | Last Updated 6 Jan 2012
Article Copyright 2012 by Aleksey Shurtygin
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid