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();
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());
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.
History
- 20th August, 2003: Initial post
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.