A Simple Configuration Pattern
Most apps need to allow for some sort of configuration. Using the .NET built in appSettings functionality to read settings from an app.config or web.config is perfect for simple cases. Sometimes, though, you need to handle settings that are more complicated or repeating. Creating section handlers can provide an elegant means of retrieving these more complicated settings. In my experience, however, using section handlers can be thought of as difficult. I thought I'd post some example code to show that it's really easy to do if you follow a basic pattern.
Step 1: Design Settings Object
Design an object that represents the settings that you'll be retrieving. In the case of repeating settings, create a second type and add an array of that type as a parameter. Decorate the object with XML attributes as desired.
public class ComponentConfigObject
{
[XmlArray("configItems")]
[XmlArrayItem("configItem")]
public ConfigItem[] ConfigItems;
}
public class ConfigItem
{
[XmlAttribute("a")]
public string A;
[XmlAttribute("b")]
public int B;
}
Step 2: Setup Config File
Simply add a section element to the configSections element of the configuration file. Then add the an element with the name specified in the section element. Inside that element add XML that represents your setting object.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="myComponentConfiguration" type="MyNamespace1.MyNamespace2.ComponentConfigSectionHandler, myAssembly" />
</configSections>
<myComponentConfiguration>
<ComponentConfigObject>
<configItems>
<configItem a="abcd" b="50" />
<configItem a="fghi" b="100" />
</configItems>
</ComponentConfigObject>
</myComponentConfiguration-->
<!-- don't need appSettings -->
<appSettings></appSettings>
</configuration>
Step 3: Create Section Handler
Create a class that implements the IConfigurationSectionHandler interface. This is easy as there is just one method, Create, to implement. All that is needed is to create our settings from the XML section provided to us. Manual parsing of XML is a waste of time, problematic, and rarely, if ever, can I be convinced of its value. Let the Framework do the work for you. This is why you created a settings object. Simply instantiate a serializer and create your settings object by passing in the first child node of the XML section.
public class ComponentConfigSectionHandler : IConfigurationSectionHandler
{
public ComponentConfigSectionHandler()
{
}
#region IConfigurationSectionHandler Members
public object Create(object parent, object configContext, System.Xml.XmlNode section)
{
XmlSerializer ser = new XmlSerializer(typeof(ComponentConfigObject));
XmlTextReader xmlReader = new XmlTextReader(section.FirstChild.OuterXml.Trim(), section.NodeType, null);
ComponentConfigObject config = (ComponentConfigObject)ser.Deserialize(xmlReader);
return config;
}
#endregion
}
Step 4: Get Settings
When it comes time to look up the settings, you simply ask for them by name.
ComponentConfigObject config = (ComponentConfigObject)System.Configuration.ConfigurationSettings.GetConfig("myComponentConfiguration");
This will use the IConfigurationSectionHandler you created to return your settings.
See, a nice, easy and elegant way to handle a related group of settings.