Click here to Skip to main content
Licence 
First Posted 14 Jul 2003
Views 157,047
Bookmarked 67 times

An extension for a Configuration Settings class in .NET

By | 19 Aug 2003 | Article
A class to allow easy access and updating to configuration settings for your .NET application.

Introduction

In the System.Configuration namespace you will find a sealed class called ConfigurationSettings which provides access to a static NameValueCollection entitled AppSettings.  This ConfigurationSettings class allows you to access information stored in an XML-based configuration file.  This file is typically titled the name of your executable followed by a ".config" file extension.  The main inherent problem with this class is that your strictly only allowed to read values from configuration file through this class, no updating method is provided.  I have addressed this issue below in the following ConfigSettings class.  I have also updated the class to implement the IConfigurationSectionHandler interface which I plan on detailing within this article as soon as I have more time (Thanks Heath for the suggestion).  Reflector was a big help along with simply reading the documentation.  As always, if I left something out, please leave a message at the bottom.  Hope this is of some help.

The following namespaces are required:

using System;
using System.IO;
using System.Xml;
using System.Reflection;
using System.Collections;
using System.Globalization;
using System.Configuration;
using System.Collections.Specialized;

The class looks like the following:

namespace Configuration
{

    public class ConfigSettingsSectionHandler : IConfigurationSectionHandler
    {
	static ConfigSettingsSectionHandler(){}

	public object Create(object parent, object configContext, 
                                                   System.Xml.XmlNode section)
	{
	    NameValueCollection col = new NameValueCollection(
	    new CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture), 
		   new CaseInsensitiveComparer(CultureInfo.InvariantCulture));

		foreach(XmlNode node in section.ChildNodes)
		{
			switch(node.Name)
			{	
				case "add":
				col.Add(node.Attributes["key"].Value, 
					node.Attributes["value"].Value);
				break;
			}
		}
		return col;
	  }
     }
	

public class ConfigSettings	
{
	private string _configfilename, _query, _sectionName;
	private XmlDocument _doc;
	private XmlTextWriter _writer;
	private XmlNodeList _nodes;
	private XmlElement  _appsettings, _node;
	private XmlAttribute _attr1, _attr2;
	private bool _bFileExists;

	public ConfigSettings()
	{
		if(File.Exists(Assembly.GetExecutingAssembly().ToString() + 
                                                               ".exe.config"))
		{
			this.ConfigFileName = 
                   Assembly.GetExecutingAssembly().ToString() + ".exe.config";
			_bFileExists = true;
		}
		else
		{
			_bFileExists = false;
		}
	}

	public ConfigSettings(string ConfigFileName)
	{
		if(File.Exists(ConfigFileName))
		{
			this.ConfigFileName = ConfigFileName;
			_bFileExists = true;
		}
		else
		{
			_bFileExists = false;
		}
	}

		
	public NameValueCollection GetConfig()
	{
		return (NameValueCollection)ConfigurationSettings.GetConfig(
                                                                 SectionName);
	}

	public NameValueCollection GetConfig(string SectionName)
	{
	    return (NameValueCollection)ConfigurationSettings.GetConfig(
                                                                 SectionName);
	}

	public string GetValue(string AttributeName)
	{
		NameValueCollection col = this.GetConfig();
		if(col[AttributeName] != null)
		       return Convert.ToString(col[AttributeName].ToString());
		else
			return String.Empty;
	}

	public void SetValue(string AttributeName, string Value)
	{
	        XmlDocument = new XmlDocument();
		XmlDocument.Load(this.ConfigFileName);
	        Query = "configuration/" + SectionName;
		AppSettingsNode = 
                    (XmlElement)this.XmlDocument.SelectSingleNode(this.Query);
		if(AppSettingsNode == null)
			return;
		Query += "/add[@key='" + AttributeName.ToString() + "']";
		XmlNodeList = this.XmlDocument.SelectNodes(this.Query);
		if(XmlNodeList.Count > 0)
			Node = (XmlElement)XmlNodeList[0];
		else
		{
			Node = this.XmlDocument.CreateElement("add");
			XmlAttribute1 = 
                                      this.XmlDocument.CreateAttribute("key");
			XmlAttribute1.Value = AttributeName.ToString();
			Node.Attributes.SetNamedItem(XmlAttribute1);
			XmlAttribute2 = 
                                    this.XmlDocument.CreateAttribute("value");
			Node.Attributes.SetNamedItem(XmlAttribute2);
			AppSettingsNode.AppendChild(Node);
		}
		Node.Attributes["value"].Value = Value.ToString();
		this.XmlDocument.Save(this.ConfigFileName);
	}


	public void CreateConfigFile(string ConfigFileName, 
                                                           string sectionName)
	{
	        FileStream file = new FileStream(ConfigFileName, 
                                                   System.IO.FileMode.Create);
		file.Close();
		Writer = new XmlTextWriter(ConfigFileName, 
                                                System.Text.Encoding.Unicode);
		Writer.Formatting = Formatting.Indented;
		Writer.WriteRaw("<?xml version=\"1.0\" ?>\n");
		Writer.WriteRaw("<configuration>\n");
		Writer.WriteRaw("<configSections>\n");
		string str = String.Format("<section type="{1}" name="{0}" />\n", 
                       "\"" + sectionName.ToString() + "\"",
             "\"Configuration.ConfigSettingsSectionHandler, Configuration\"");
		Writer.WriteRaw(str.ToString());
		Writer.WriteRaw("</configSections>\n");
		Writer.WriteRaw("<" + sectionName.ToString() + ">\n");
		Writer.WriteRaw("</" ? + sectionName.ToString()>\n");
		Writer.Flush();
		Writer.Close();
		}
	}

        public string ConfigFileName
	{
		get{ return _configfilename;}
		set{ _configfilename = value;}
	}
	public XmlDocument XmlDocument
	{
		get{ return _doc;}
		set{ _doc = value;}
	}
	public XmlTextWriter Writer
	{
		get{ return _writer;}
		set{ _writer = value;}
	}
	public XmlNodeList XmlNodeList
	{
		get{ return _nodes;}
		set{ _nodes = value;}
	}
	public XmlElement AppSettingsNode
	{
		get{ return _appsettings;}
		set{ _appsettings = value;}
	}
	public XmlElement Node
	{
		get{ return _node;}
		set{ _node = value;}
	}
	public string Query
	{
		get{ return _query;}
		set{ _query = value;}
	}
	public XmlAttribute XmlAttribute1
	{
		get{ return _attr1;}
		set{ _attr1 = value;}
	}
	public XmlAttribute XmlAttribute2
	{
		get{ return _attr2;}
		set{ _attr2 = value;}
	}
	public string SectionName
	{
		get{ return _sectionName;}
		set{ _sectionName = value;}
	}
	public bool FileExists
	{
		get{return _bFileExists;}
		set{_bFileExists = value;}
	}

}

Using the class

To use the class you will simply do one of the following:

private ConfigSettings config = new ConfigSettings();</FONT>

and then just use either the GetConfig(), GetValue(), SetValue() methods as such:

  private void Form1_Load(object sender, System.EventArgs e)
  {
     config.ConfigFileName = "Test.exe.config";
     config.SectionName = "ApplicationData";
     string height = config.GetValue("Height");
     if(height != String.Empty)
         this.Height = Convert.ToInt32(height.ToString());

     // or return the whole collection of a particular section.

     NameValueCollection collection = config.GetConfig("ApplicationData");
     if(collection["Width"] != null)
          this.Width = Convert.ToInt32(collection["Width"].ToString());
}
  private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
  {
        config.SectionName = "ApplicationData";
        config.SetValue("Height", this.Height.ToString());
        config.SetValue("Width", this.Width.ToString());
  }

Conclusion

I just thought I would post the latest updates, there are still many changes to come including a code clean-up as well as more methods to interact with the config file.  Let me know what you think.

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

About the Author

Nick Parker

Software Developer (Senior)

United States United States

Member

Nick graduated from Iowa State University with a B.S. in Management Information System and a minor in Computer Science. Nick works for Zetetic.
 
Nick has also been involved with the Iowa .NET User Group since it's inception, in particular giving presentations over various .NET topics. Nick was awarded the Visual C# MVP award from Microsoft for four years in a row.
 
In his mystical spare time he is working on a development project called "DeveloperNotes" which integrates into Visual Studio .NET allowing developers easy access to common code pieces. He is also a fan of using dynamically typed languages to perform unit testing, not to mention how he loves to talk about himself in the third person.

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. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generalproblem with the config file Pinmembermark chester goking15:30 28 Jan '09  
GeneralRe: problem with the config file Pinmembermark chester goking16:13 28 Jan '09  
GeneralThis code crashes with a file Browser PinmemberKesler9:05 14 Dec '05  
GeneralExtremely bad code. Pinmembere_zolotko23:41 26 Oct '05  
GeneralRe: Extremely bad code. PinmemberHerbert Sauro11:13 21 Aug '07  
GeneralVery bad code Pinmemberborner23:20 12 Oct '05  
GeneralConstructor don´t works if tool using in dll Pinmembergbalog7:41 11 Jan '05  
Constructor don´t works if tool using in dll, because Assembly.GetExecutingAssembly() gets the assembly from the dll. The good news is, no one uses bool _bFileExists; drop it.
 
The solution is:
 
public ConfigSettings(string sConfigFile)
{
ConstructorHelper(sConfigFile);
}
 

private void ConstructorHelper(string sConfigFile)
{
if(File.Exists(sConfigFile))
{
this.ConfigFileName = sConfigFile;
}
else
{
throw new Exception("Config File '"+sConfigFile+"' Dosn´t exist");
}
}

 

And the usage
 
ConfigSettings conf = new ConfigSettings(Assembly.GetExecutingAssembly().Location + ".config");
 
I will using the module intensively in the next few days, the Result I will post here.
 
Greetings: Georg Balog

 
Georg Balog
eandb@axelero.hu
GeneralRe: Constructor don´t works if tool using in dll PinprotectorNick Parker8:06 11 Jan '05  
Generalwow your class deletes the config file like a champ ! :mad: Pinmember^^o000o^^23:02 31 Dec '04  
GeneralGetValue() and SetValue() problems PinmemberManster3:46 13 Apr '04  
GeneralRe: GetValue() and SetValue() problems PineditorNick Parker4:03 13 Apr '04  
GeneralRe: GetValue() and SetValue() problems PinmemberSaurweinAndreas14:08 27 Apr '04  
GeneralHave to restart the application to see changes PinmemberMaxerCode13:10 6 Jan '04  
GeneralRe: Have to restart the application to see changes PineditorNick Parker17:07 6 Jan '04  
GeneralRe: Have to restart the application to see changes PinmemberMaxerCode18:09 6 Jan '04  
QuestionGetValue failing??? PinmemberRussq2:07 20 Oct '03  
AnswerRe: GetValue failing??? PineditorNick Parker3:35 20 Oct '03  
GeneralRe: GetValue failing??? PinmemberRussq3:44 20 Oct '03  
GeneralRe: GetValue failing??? PinmemberRussq3:47 20 Oct '03  
GeneralRe: GetValue failing??? PinmemberRussq3:49 20 Oct '03  
GeneralRe: GetValue failing??? PinmemberMithrang11:32 17 Nov '03  
GeneralRe: GetValue failing??? PineditorNick Parker12:26 17 Nov '03  
GeneralRe: GetValue failing??? PinmemberMithrang12:52 17 Nov '03  
GeneralRe: GetValue failing??? PineditorNick Parker15:58 17 Nov '03  
GeneralRe: GetValue failing??? PinmemberRussq22:38 17 Nov '03  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    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 | Mobile
Web02 | 2.5.120528.1 | Last Updated 20 Aug 2003
Article Copyright 2003 by Nick Parker
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid