Introduction
The .NET Compact Framework does not contain an AppSettings
class like the full framework. On the full .NET Framework a developer could gain access to settings stored in the App.Config file by creating a name value collection from the System.Configuration.ConfigurationSettings.AppSettings
class. As an advocate of uniformity, I wanted to create something that had similar functionality on the Compact Framework. This article will show you what I came up with.
Using the code
My first step was to create an XML file that looked a lot like the App.Config file in .NET.
="1.0" ="utf-8"
<configuration>
<appSettings>
<add key="ServerIP" value="192.168.5.22" />
<add key="UserName" value="testuser" />
<add key="Password" value="jdhs822@@*" />
<add key="PhoneNumber" value="5555555555" />
<add key="TimeOut" value="60" />
<add key="LastTransmit" value="03/03/2004 9:12:33 PM" />
<add key="DatabasePath" value="\Program Files\DB\test.sdf" />
</appSettings>
</configuration>
I named this file Settings.xml and added it to my project with a build action of content. This ensures that the file will get downloaded to my program's executing folder.
My next step was to create a new class called Settings
. This class contains only static members so the settings are accessed from the file only once during program execution and the entire program will have easy access to these values.
I wanted the settings to be loaded as soon as the settings were accessed, so I created a static constructor and placed my XML parsing code inside the constructor.
m_settings
is a NameValueCollection
that stores all of the settings.
public class Settings
{
private static NameValueCollection m_settings;
private static string m_settingsPath;
static Settings()
{
m_settingsPath = Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
m_settingsPath += @"\Settings.xml";
if(!File.Exists(m_settingsPath))
throw new FileNotFoundException(
m_settingsPath + " could not be found.");
System.Xml.XmlDocument xdoc = new XmlDocument();
xdoc.Load(m_settingsPath);
XmlElement root = xdoc.DocumentElement;
System.Xml.XmlNodeList nodeList = root.ChildNodes.Item(0).ChildNodes;
m_settings = new NameValueCollection();
m_settings.Add("ServerIP", nodeList.Item(0).Attributes["value"].Value);
m_settings.Add("UserName", nodeList.Item(1).Attributes["value"].Value);
m_settings.Add("Password", nodeList.Item(2).Attributes["value"].Value);
m_settings.Add("PhoneNumber",
nodeList.Item(3).Attributes["value"].Value);
m_settings.Add("TimeOut", nodeList.Item(4).Attributes["value"].Value);
m_settings.Add("LastTransmit",
nodeList.Item(5).Attributes["value"].Value);
m_settings.Add("DatabasePath",
nodeList.Item(6).Attributes["value"].Value);
}
}
Now, we need some public accessors to retrieve the values from the NameValueCollection
.
public static string ServerIP
{
get { return m_settings.Get("ServerIP"); }
set { m_settings.Set("ServerIP", value); }
}
public static string UserName
{
get { return m_settings.Get("UserName"); }
set { m_settings.Set("UserName", value); }
}
The only thing left to do is to add a method for updating our settings. The XmlTextWriter
class provides us with a light-weight mechanisim for writing xml to a FileStream
. We iterate through the NameValueCollection
and create the settings in xml.
public static void Update()
{
XmlTextWriter tw = new XmlTextWriter(m_settingsPath,
System.Text.UTF8Encoding.UTF8);
tw.WriteStartDocument();
tw.WriteStartElement("configuration");
tw.WriteStartElement("appSettings");
for(int i=0; i<m_settings.Count; ++i)
{
tw.WriteStartElement("add");
tw.WriteStartAttribute("key", string.Empty);
tw.WriteRaw(m_settings.GetKey(i));
tw.WriteEndAttribute();
tw.WriteStartAttribute("value", string.Empty);
tw.WriteRaw(m_settings.Get(i));
tw.WriteEndAttribute();
tw.WriteEndElement();
}
tw.WriteEndElement();
tw.WriteEndElement();
tw.Close();
}
Now we can easily access our settings from anywhere in our application!