Pages

Thursday, August 2, 2012

XML Configuration Files for .NET Micro Framework Applications


All applications require configuration files; we use them to customize behavior and to set parameters unknown at compile time, or those that may change over time (such as the database connection string, the address of the mail server, etc.).
.NET supplies the class ConfigurationManager, or WebConfigurationManager for Web applications, to recover the configuration parameters recorded in the CONFIG file. This class is not included in the .NET Micro Framework.
However, we can create a smaller version of the ConfigurationManager.  The .NET Micro Framework can read the appSettings section of the standard .NET configuration file, since they are simple XML files.
public static class ConfigurationManager
{
    private const string APPSETTINGS_SECTION = "appSettings";
    private const string ADD = "add";
    private const string KEY = "key";
    private const string VALUE = "value";
    private static Hashtable appSettings;
    static ConfigurationManager()
    {
        appSettings = new Hashtable();
    }
    public static string GetAppSetting(string key)
    {
        return GetAppSetting(key, null);
    }
    public static string GetAppSetting(string key, string defaultValue)
    {
        if (!appSettings.Contains(key))
        return defaultValue;
        return (string)appSettings[key];
    }
    public static void Load(Stream xmlStream)
    {
        using (XmlReader reader = XmlReader.Create(xmlStream))
        {
            while (reader.Read())
            {
                switch (reader.Name)
                {
                    case APPSETTINGS_SECTION:
                        while (reader.Read())
                        {
                            if (reader.Name == APPSETTINGS_SECTION)
                                break;
                            if (reader.Name == ADD)
                            {
                                var key = reader.GetAttribute(KEY);
                                var value = reader.GetAttribute(VALUE);
                                //Debug.Print(key + "=" + value);
                                appSettings.Add(key, value);
                            }
                        }
                        break;
                }
            }
        }
    }
}
The most important method of the class is Load, which takes a Stream input object containing the configuration file, and reads it with an XmlReader, in search of the appSettings tag. When it finds it, it processes all elements with name ADD, and for each, extracts the values ​​of the key attributes, saving them in theHashtable appSettings. We then call the GetAppSettings function, which returns the value corresponding to the specified key; it is also an overload that returns a default value if the key does not exist.
Let’s take an example. We create a new .NET Gadgeteer application and connect the SD Card module to an F socket of the FEZ Spider. We need an SD card that contains, in the root directory of the store, the following configuration file in .NET standard format, with the name Application.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSetting>
    <add key="Key1" value="Value1" />
    <add key="Key2" value="Value2" />
    <add key="Key3" value="Value3" />
    <add key="hostName" value="www.google.it" />
    <add key="port" value="25" />
  </appSettings>
</configuration>
Finally, in the Program.cs file, we read the file from the memory card and pass it to theConfigurationManager:
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using System.IO;
using Gadgeteer.Modules.GHIElectronics;
namespace AppSettingsExample
{
    public partial class Program
    {
        void ProgramStarted()
        {
            sdCard.SDCardMounted += new SDCard.SDCardMountedEventHandler(sdCard_SDCardMounted);
            Debug.Print("Program Started");
        }
        private void sdCard_SDCardMounted(SDCard sender, GT.StorageDevice SDCard)
        {
            // Read configuration file.
            string filePath = "Application.config";
            using (Stream configStream = SDCard.OpenRead(filePath))
            {
                // Loads settings.
                ConfigurationManager.Load(configStream);
            }
            // Retrieve some values.
            var host = ConfigurationManager.GetAppSetting("hostName");
            var port = ConfigurationManager.GetAppSetting("port");
            var userName = ConfigurationManager.GetAppSetting("userName", "anonymous");
            Debug.Print("HostName: " + host);
            Debug.Print("Port: " + port);
            Debug.Print("Username: " + userName);
        }
    }
}
The event sdCard_SDCardMounted is generated when the memory card is inserted into the module. We read the Application.config file with the OpenRead method and pass it to the ConfigurationManager.Loadmethod. At this point, we recover some example values through calls to GetAppSetting and we print them in the Debug output window of Visual Studio. Notice that in the third case we require the value of key username, than is not present in the configuration file, and therefore comes back with the default value, that is anonymous.
The ConfigurationManager class is easily extensible. To support new sections of the configuration file, add branches to the switch of the Load method.
This application is available for download.

Reference:

No comments:

Post a Comment