.NET AppConfig Replacement with Linq To XML
by David on Nov.28, 2009, under .NET, Software-Development
Just lately I had to implement a configuration for some Service. Where to get the data from, when to start the processing, how to behave in certain cases and so on. Then someone gave me the hint, that with Linq to XML it would be quite easy and flexible to build some configuration.
Configuration means to me:
Having some static class which I can access from all over the application.
public class IBFactsheetsConfiguration
{
public static string FolderWithFactsheets { get; set; }
….
}
Now with an Appconfig I would have to write the Mapping from the xml/ConfigSections by hand(AFAIK). This can be quite tedious.
Considering Linq To XMl I would be best to have some class which would do the mapping itself once for ever. So that the configClass from above would just derive from that basic Mapping class and thats all.
Now as I use only the public static properties of my configuration class, it requires just a reflectional method which gets all those properties. Then as I have them, I only have to persist the data into xml. Vice versa I have to be able to read the config into the class from the xml.
To keep it short, here is the basic Mapping Class:
public class Configuration<T>
{
//load the xml file, uses reflectional method PropertyInfo.SetValue
public static void Initialize(string ConfigFileWithPath)
{
XDocument xmlDoc = new XDocument();
xmlDoc = XDocument.Load(ConfigFileWithPath + typeof(T).Name + “.xml”);
foreach (PropertyInfo info in GetPropertyInfos())
{
info.SetValue(null, (from p in xmlDoc.Descendants(info.Name) select p.Value).First(), null);
}
}
// provides all the static public properties of the class
private static PropertyInfo[] GetPropertyInfos()
{
PropertyInfo[] propertyInfos;
propertyInfos = typeof(T).GetProperties(BindingFlags.Public |
BindingFlags.Static);
// sort properties by name
return propertyInfos.OrderBy(a => a.Name).ToArray();
}
//saves the properties to xml using LinQ to XML
public static void SaveConfigTo(string Path)
{
var custsDoc = new XDocument(
new XDeclaration(”1.0″, “utf-8″, “yes”),
new XComment(typeof(T).FullName),
new XElement(typeof(T).Name,
from row in GetPropertyInfos()
select new XElement(row.Name, row.GetValue(null, null))));
//save the Xdoc to the Xml File
custsDoc.Save(Path + typeof(T).Name + “.xml”);
}
}
Here comes the Configuration class:
public class IBFactsheetsConfiguration : Configuration<IBFactsheetsConfiguration>
{
public static string FolderWithFactsheets { get; set; }
………….
}
this time its derived from Configuration<IBFactsheetsConfiguration>
UsageScenario:
First I have to initialize the static class once before any usage.
public void InitializeConfigOnce()
{
IBFactsheetsConfiguration.Initialize(@”D:\SomePath\”);
}
this Initializes the class from an xmlfile called: “IBFactsheetsConfiguration.xml” in d:\SomePath
Now I can access the Configuration from anywhere with
public void someMethodOrOther()
{
string someConfig = IBFactsheetsConfiguration.FolderWithFactsheets;
}
Now thats it all. One could provide support for hierarchal Config Classes. Now thats left for the future.
Any comments are welcome.