Introduction
The .NET Framework gives developers and administrators control and flexibility over the way applications run. An administrator can control which protected resources an application can access, which versions of assemblies an application will use, and where remote applications and objects are located. Developers can put settings in configuration files, eliminating the need to recompile an application every time a setting changes.
But for unknown reasons, this facility is not available for .NET Compact Framework developers. This utility aims at achieving the similar flexibility of configuring .NET Compact Framework applications, where in the developers can put their settings in an XML configuration file named as SmartConfig.xml, eliminating the need to recompile an application every time a setting changes.
This utility impersonates the .NET Framework configuration management in the way it is defined and used to pickup information at runtime, except that it very precise in the way it handles only the custom configSections
defined by the developer. It does not have any predefined configuration sections such as <system.diagnostics>
.
SmartDeviceUtilities.ConfigurationManagement
assembly encompasses various class definitions and interfaces which can be used to achieve the task of configuration management in applications that target .NET Compact Framework.
About SmartDeviceUtilities.ConfigurationManagement Assembly
ConfigurationSettings
class - Provides access to configuration settings in a specified configuration section. This class exposes a public static method GetConfig()
, which takes the name of the configuration section node as the parameter of type string and returns the instance of the type name declared as the section's handler in the section node of SmartConfig.xml.
This class also exposes a public static property AppSettings
, which returns a NameValueCollection
filled with key-value pairs defined in the appSettings
section of SmartConfig.xml file.
ConfigurationSectionHandlerActivator
class: This class defines an internal static method named ReadConfigurationSettings()
, which does the work of activating the section handlers defined in the various configuration section nodes.
IConfigSectionHandler
interface: Defines the contract that all smart device configuration section handlers must implement in order to participate in the resolution of configuration settings.
ReadOnlyNameValueCollection
class - Derived from NameValueCollection
. This class exposes a public method SetReadOnly()
, when invoked marks the collection as "Read Only".
Background
A configuration file can contain information that the application reads at run time. Developers use configuration sections to specify this information in configuration files. Configuration sections have two parts: a configuration section declaration and the configuration settings. You can put configuration section declarations and configuration settings in the SmartConfig.xml file.
At run time, section handlers, which are classes that implement the IConfigSectionHandler
interface, read settings in the SmartConfig.xml.
In addition to the support for custom configuration sections, SmartConfig.xml also defines a default section named appSettings
, which is a collection of nodes defined with key
and value
attributes. There is no need to write a separate handler for appSettings
configuration section as this section will be handled internally and can be accessed by the public static AppSettings
property of ConfigurationSettings
class.
SmartConfig.xml - Configuration section's schema
<configuration>
<appSettings>
<configSections>
<section>
<Custom element for configuration section>
<Custom element for configuration section>
How does it work?
The class that is defined as a configuration section handler should implement the interface IConfigSectionHandler
. By defining the IConfigSectionHandler.Create
method, the class is designated as a valid configuration section handler. When the static ConfigurationSettings.GetConfig(sectionName)
method is called by the client code to get the configuration settings of a particular configuration section, the method reads the static ConfigurationSectionHandlerActivator.IsActivated
property which returns true
if the config section handlers are already activated. If the property returns false
, the static ConfigurationSectionHandlerActivator.ReadConfigurationSettings()
method will be invoked, which reads the SmartConfig.xml and stores the config section handler objects in a synchronized version of Hashtable
, with the section name as key and the ConfigurationSectionHandlerActivator.IsActivated
is set to true
, so that subsequent calls to the GetConfig
method returns values from the Hashtable
directly.
ConfigurationSettings.GetConfig(sectionName)
method definition:
#region GetConfig
public static object GetConfig(String sectionName)
{
if (!ConfigurationSectionHandlerActivator.IsActivated)
ConfigurationSectionHandlerActivator.ReadConfigurationSettings();
if (configSectionsStore.ContainsKey(sectionName))
return configSectionsStore[sectionName];
else
return null;
}
#endregion
The ConfigurationSectionHandlerActivator.ReadConfigurationSettings()
method also reads the appSettings
section in SmartConfig.xml file and stores the key-value pairs in a ReadOnlyNameValueCollection
object.
This key-value pairs can be accessed by the public indexer or Get(key)
method of the read-only NameValueCollection
object returned by the static AppSettings
property of ConfigurationSettings
class.
Using the code
This section describes how to use SmartDeviceUtilities.ConfigurationManagement
assembly in your code.
Step 1: Download the source code file published along with this article.
Step 2: Add Project or Assembly reference to SmartDeviceUtilities.ConfigurationManagement
in your project.
Step 3: Create a new XML file named SmartConfig.xml in your project folder.
Step 4: Declare configuration sections and access configuration settings. Configuration section information can be grouped into two main parts in the configuration file: the configuration section declaration area and the configuration section settings area. Put configuration section declarations in the <configSections>
element. Create a new configuration section by declaring it in a <section>
element inside the <configSections>
element. The <section>
element has two properties: the name attribute, which is the name of the element that contains the information the section handler reads; the type attribute, which has two parts, the name of the class that reads the information and the assembly that encompasses the type, separated by a ","(comma). The syntax of the configuration setting depends on the section handler that is associated with the configuration section. SmartConfig.xml also supports a default configuration section named <appSettings>
, which is a collection of nodes defined with key
and value
attributes. The following example shows how to declare appSettings configuration section and a custom section in SmartConfig.xml that uses the MyCongifSectionHandler
class.
<configuration>
<appSettings>
<add key="Key 1" value="app Settings Value 1" />
<add key="Key 2" value="app Settings Value 2" />
<add key="Key 3" value="app Settings Value 3" />
</appSettings>
<configSections>
<section name="mySection"
type="MySampleApplication.MyConfigSectionHandler,MySampleApplication" />
</configSections>
<mySection setting1="Value1" setting2="value two" setting3="third value" />
</configuration>
Step 5: Define the configuration section handler class that implements IConfigSectionHandler
interface. The following example shows the definition of MyConfigSectionHandler
class that is included in the sample download demo project.
using System;
using System.Xml;
using SmartDeviceUtilities.ConfigurationManagement;
namespace MySampleApplication
{
public class MyConfigSectionHandler : IConfigSectionHandler
{
private string setting1;
private string setting2;
private string setting3;
public MyConfigSectionHandler()
{
}
public string Setting1
{
get
{
return setting1;
}
set
{
setting1 = value;
}
}
public string Setting2
{
get
{
return setting2;
}
set
{
setting2 = value;
}
}
public string Setting3
{
get
{
return setting3;
}
set
{
setting3 = value;
}
}
#region IConfigSectionHandler Members
public object Create(XmlNode sectionNode)
{
try
{
MyConfigSectionHandler myConfigSectionHandler=
new MyConfigSectionHandler();
if (sectionNode == null)
{
throw new ArgumentNullException("Configuration" +
" section node cannot be null");
}
myConfigSectionHandler.Setting1 =
sectionNode.Attributes["setting1"].Value;
myConfigSectionHandler.Setting2 =
sectionNode.Attributes["setting2"].Value;
myConfigSectionHandler.Setting3 =
sectionNode.Attributes["setting3"].Value;
return (myConfigSectionHandler);
}
catch
{
throw;
}
}
#endregion
}
}
Step 6: Accessing and using the appSettings
configuration information in your application. The following code snippet shows how to access appSettings
configuration section.
private void GetAppSettings()
{
StringBuilder builder = new StringBuilder();
NameValueCollection collection = ConfigurationSettings.AppSettings;
foreach (String key in collection)
{
builder.Append(key);
builder.Append(": ");
builder.Append(collection[key]);
builder.Append(", ");
}
}
Step 7: Accessing and using the configuration information in your application. The following code snippet shows how to access a particular configuration section object.
public void GetMyConfigSettings()
{
MyConfigSectionHandler myConfigSectionHandler =
(MyConfigSectionHandler) ConfigurationSettings.GetConfig("mySection");
String setting1 = myConfigSectionHandler.Setting1;
String setting2 = myConfigSectionHandler.Setting2;
String setting3 = myConfigSectionHandler.Setting3;
}
History
- 5 April 2004 - Initial version.
- 9 April 2004 - Updated - Support for
appSettings
configuration section.