Few things in .Net are as powerful, or as obscure as app.config and web.config. Many people think these files are little more than glorified .ini files wrapped in XML. I've heard this more times than I can mention and I can understand why some may think that. XML seems to be one of those things that, no matter how lame your implementation is, if you are using it then you're 'cool.' As I mentioned in Going Remote, you can use .config files within the Remoting framework so you can actually add new types to your remoting framework without having to recompile the application. In an enterprise scenario, this is huge. To be honest, I think you could write a rather lengthy book on .config files in .NET and to be honest, I can't think of where the 'endpoint' would actually be since they are so flexible and powerful. In this article, I'm going to walk you through creating a custom configuration section. Now, what I'm doing here isn't that revolutionary becuase you can essentially get to the same place using AppSettings. However appSettings is a predefined section in AppConfig and what if you had 100+ settings. Chances are you'd want to group them logically into some sane order, the same way you use Namespaces and regions within your code.
Anyway, here's some code to use for a custom configuration section handler:
First, I create a class that models the configuration values I want to use. There's nothing special about this class and I intentionally used a silly example to highlight the fact that you can do whatever you want with it.
public class BillRyan { #region Private Variables private System.String mWhatIsBillListeningTo; private System.String mGirlfriend; private System.String mBillsSideKick; private System.String mRollingPaperBalls; private System.String mStudying1; private System.String mStudying2; #endregion #region Public Methods public System.String WhatIsBillListeningTo { get{return mWhatIsBillListeningTo;} set{mWhatIsBillListeningTo = value;} } public System.String BillsSideKick { get{return mBillsSideKick;} set{mBillsSideKick = value;} } public System.String Girlfriend { get{return mGirlfriend;} set{mGirlfriend = value;} } public System.String RollingPaperBalls { get{return mRollingPaperBalls;} set{mRollingPaperBalls = value;} } public System.String Studying1 { get{return mStudying1;} set{mStudying1 = value;} } public System.String Studying2 { get{return mStudying2;} set{mStudying2 = value;} } #endregion public BillRyan(){} } |
| using System; using System.Xml; using System.Configuration; namespace KDN.Configuration { /// <summary> /// Summary description for BillRyanConfigSectionHandler. /// public class BillRyanConfigSectionHandler : System.Configuration.IConfigurationSectionHandler { public BillRyanConfigSectionHandler(){} #region IConfigurationSectionHandler Members public object Create(object parent, object configContext, System.Xml.XmlNode section) { try { BillRyan Settings = new BillRyan(); if (section == null) { return Settings; } XmlNode CurrentAttribute; XmlAttributeCollection NodeAttributes = section.Attributes; XmlAttributeCollection FileAttributes = null; CurrentAttribute = NodeAttributes.RemoveNamedItem("file"); if (CurrentAttribute != null) { string Directory = System.IO.Path.Combine( AppDomain.CurrentDomain.BaseDirectory, CurrentAttribute.Value); if (System.IO.File.Exists(Directory)) { XmlDocument FileDocument = new XmlDocument(); FileDocument.Load(Directory); XmlNode SettingsNode = FileDocument.SelectSingleNode("ProgramInfo"); if (SettingsNode != null) { FileAttributes = SettingsNode.Attributes; } } } Settings.BillsSideKick = GetAttributeValue("BillsSideKick", NodeAttributes, FileAttributes); Settings.WhatIsBillListeningTo = GetAttributeValue("WhatIsBillListeningTo", NodeAttributes, FileAttributes); Settings.Girlfriend = GetAttributeValue("Girlfriend", NodeAttributes, FileAttributes); Settings.RollingPaperBalls = GetAttributeValue("RollingPaperBalls", NodeAttributes, FileAttributes); Settings.Studying1 = GetAttributeValue("Studying1", NodeAttributes, FileAttributes); Settings.Studying2 = GetAttributeValue("Studying2", NodeAttributes, FileAttributes); return Settings; } catch (Exception exc) { throw new ConfigurationException("Error loading iDec configuration.", exc, section); } } private string GetAttributeValue( string attributeName, XmlAttributeCollection nodeAttributes, XmlAttributeCollection fileAttributes) { XmlNode CurrentAttribute = null; string ReturnValue = null; if (fileAttributes != null) { CurrentAttribute = fileAttributes.RemoveNamedItem(attributeName); } if (CurrentAttribute != null) { ReturnValue = CurrentAttribute.Value.Trim(); } else { CurrentAttribute = nodeAttributes.RemoveNamedItem(attributeName); if (CurrentAttribute != null) { ReturnValue = CurrentAttribute.Value.Trim(); } } return ReturnValue; } #endregion } } |
| <configuration> <configSections> <section name="ProgramInfo" type="KDN.Configuration.BillRyanConfigSectionHandler, WebConfigRocks" /> configSections> <ProgramInfo type="KDN.Configuration.BillRyanConfigSectionHandler, WebConfigRocks" WhatIsBillListeningTo="Back Down - 50 Cent" Girlfriend="Kim" BillsSideKick="Sonny the Coding Cuckoo" RollingPaperBalls="true" Studying1="Sharepoint" Studying2="Sql Server 2005"/> configuration> |
| private void button1_Click(object sender, System.EventArgs e) { BillRyan BillsSettings = (BillRyan)System.Configuration.ConfigurationSettings.GetConfig("ProgramInfo"); lb.Items.Add(BillsSettings.BillsSideKick); //Back Down - 50 Cent lb.Items.Add(BillsSettings.RollingPaperBalls); //true lb.Items.Add(BillsSettings.Girlfriend); //Kim lb.Items.Add(BillsSettings.Studying1); //Sharepoint lb.Items.Add(BillsSettings.Studying2); //Sql Server 2005 } |