Beginnings of a Flexible .NET Architecture: A Simplified Config Service
Pages: 1, 2, 3
Implementation
The approach is simple enough. All of our configuration will sit in one section.
There will be classes like DefaultConfig, which will absorb this long XML
section. Once absorbed, the DefaultConfig will walk through every node of
the XML and make entries in a dictionary (or hashtable) for each key and
value. This dictionary will then satisfy client requests for
keys.
Section handler code
public class SimpleConfigurationSectionHandler :IConfigurationSectionHandler
{
public object Create(object parent, object configContext, XmlNode section)
{
return section;
} // end of method
} // end of class
DefaultConfig Code
public class DefaultConfig : IConfig {
// keep a dictionary of values
private IDictionary m_keyValuePairs
// implement methods of IConfig using the above
// dictionary details left to you
// Constructor, where it reads your SimpleConfiguration
// XML node using the section handler above
public DefaultConfig()
{
// read the xml section for general config
// Section name: SimpleConfiguration
XmlNode xmlNode =
(XmlNode)System
.Configuration
.ConfigurationSettings
.GetConfig("SimpleConfiguration");
if(xmlNode != null)
{
m_keyValuePairs = createDictionary(m_genConfigXmlNode);
}
}
}
// Here is the createdictionary
private IDictionary createDictionary(XmlNode genConfigXmlNode)
{
IDictionary ht = new Hashtable();
if(genConfigXmlNode != null &&
genConfigXmlNode.ChildNodes != null &&
genConfigXmlNode.ChildNodes.Count > 0)
{
// walk through each node
// if it is a leaf node add it to the hash table
// if it is not continue the process
walkTheNode(ht,"",genConfigXmlNode);
}
return ht;
}
// Here is how you walk the nodes recursively
// to get your keys
private void walkTheNode(IDictionary ht, string parent, XmlNode node)
{
if(node != null)
{
if (node.NodeType == XmlNodeType.Comment)
{
return;
}
if (node.HasChildNodes == false)
{
if (node.NodeType == XmlNodeType.Text)
{
// no children
string leaf = node.Value;
ht.Add(parent.ToLower(),leaf);
// end of the recursive call
return;
}
else if (node.NodeType == XmlNodeType.CDATA)
{
XmlCDataSection cdataSection = (
System.Xml.XmlCDataSection)node;
string leaf = cdataSection.Data;
ht.Add(parent.ToLower(),leaf);
// end of the recursive call
return;
}
else
{
string key = parent + "/" + node.Name;
string val = "";
ht.Add(key.ToLower(), val);
return;
}
}
else
{
string newparent = parent + "/" + node.Name;
// has children
// walk all the children
for(int i=0;i<node.ChildNodes.Count;i++)
{
// recursive call
walkTheNode(ht,newparent,node.ChildNodes[i]);
}
}
}
}
One caveat while coding this: pay special attention to how CDATA and empty text nodes are treated!
|
Related Reading
Programming .NET Web Services |
Conclusion
I hope to have conveyed that one can simplify the process of accessing configuration variables from config files, be they one or many.
This article has:
- Showed examples of how such a configuration service could be used.
- Showed how to embed HTML segments into the XML file and how to retrieve them accurately.
- Showed partial implementation code to implement such a service.
In the next article in this series, we will take this simple-minded
configuration service and extend it into a FactoryService that allows much
more flexibility in your architectures.
References
- "Evolving interfaces and implementations for backward compatibility" (Vol. 6, Issue 6, Java Developers Journal), by Satya Komatineni. Find out how one can write frameworks that can withstand changes over time.
- Design Patterns (Addison Wesley). Series of design patterns, of which factory is one.
Satya Komatineni is the CTO at Indent, Inc. and the author of Aspire, an open source web development RAD tool for J2EE/XML.
Return to .NET DevCenter

