Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Configuration Management for Smart Device Applications

0.00/5 (No votes)
8 Apr 2004 1  
This utility helps you in configuring .NET Compact Framework applications.

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
    
    /// <summary>
    /// Returns configuration settings for a user-defined configuration 
    /// section.
    /// </summary>
    /// 
    /// <param name="sectionName">The configuration section to read.</param>
    /// 
    /// <returns>The configuration settings for sectionName.</returns>
    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
{
    
    /// <summary>
    /// Sample configuration section handler
    /// </summary>
    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

        /// <summary>
        /// "Create" method implementation
        /// </summary>
        /// <param name="sectionNode"></param>
        /// <returns></returns>
        public object Create(XmlNode sectionNode)
        {
            try
            {
                
                MyConfigSectionHandler myConfigSectionHandler= 
                                        new MyConfigSectionHandler();
                
                if (sectionNode == null)
                {
                    //Probably you could pickup the exception
                    // message from a resource file.
                    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.

        /// <summary>
        /// Gets the appSettings
        /// </summary>
        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(", ");
            }
        
            //
            // TODO: Add the code that uses the configuration information here
            //
        }

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;


   //
   // TODO: Add the code that uses the configuration information here
   //

}

History

  • 5 April 2004 - Initial version.
  • 9 April 2004 - Updated - Support for appSettings configuration section.

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