Using a custom (XML) configuration section (original) (raw)
I had a need recently to build a custom configuration file reader so we could use an XML based config file to populate date to our batch emailing program. The Key/Value pairing functionality of the Standard AppSettings wouldn't work, as we had several email profiles to mail to.
Here is the code to build a custom config handler (extends IConfigurationSectionHandler)
This code needs to be in a class by itself, as the Configuration handler sees the entry in the config file for the custom handler (
And searches for a DLL in the path (I keep it in the application directory) of the same name.
This code can read application.exe.config files, web.config, machine.config etc.
using System;
using System.Collections;
using System.Xml;
using System.Configuration;
namespace emailConfigHandler
{
public class configHandler : IConfigurationSectionHandler
{
public Object Create(object parent, object configContext, XmlNode section)
{
XmlNodeList mailNodesList;
Hashtable mailNodes = new Hashtable();
mailNodesList = section.SelectNodes("mailNode");
foreach (XmlNode mailNode in mailNodesList)
{
string id;
XmlNode subject;
XmlNode body;
XmlNode from;
XmlNode smtpserver;
XmlNodeList tolist;
ArrayList Recipients = new ArrayList();
id = mailNode.Attributes.GetNamedItem("id").Value;
tolist = mailNode.SelectNodes("tolist//to");
if (tolist.Count > 0)
{
foreach (XmlNode to in tolist)
{
Recipients.Add(to.InnerText);
}
}
subject = mailNode.SelectSingleNode("subject");
body = mailNode.SelectSingleNode("body");
from = mailNode.SelectSingleNode("from");
smtpserver = mailNode.SelectSingleNode("smtpserver");
mailNodes.Add(id,new mailNode(subject.InnerText,from.InnerText,body.InnerText,smtpserver.InnerText,Recipients));
}
return mailNodes;
}
}
public class mailNode
{
private string m_subject;
private string m_from;
private string m_body;
private string m_smtpserver;
private ArrayList ma_recipients;
public mailNode(string subject, string from, string body, string smtpserver, ArrayList recipients)
{
m_subject = subject;
m_body = body;
m_from = from;
m_smtpserver = smtpserver;
ma_recipients = recipients;
}
public string Subject
{
get
{
return m_subject;
}
}
public string Body
{
get
{
return m_body;
}
}
public string From
{
get
{
return m_from;
}
}
public string smtpserver
{
get
{
return m_smtpserver;
}
}
public ArrayList To
{
get
{
return ma_recipients;
}
}
}
}
the type class is populated and put into an object array (hashtable in this case, the hashtable is retrieved by the application in need of the data at runtime:
emailConfigHandler.mailNode node=null;
string id = args[0] ;
Hashtable mailNodes = new Hashtable();
try
{
mailNodes = (Hashtable)System.Configuration.ConfigurationSettings.GetConfig("mailNodes");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
if (mailNodes.ContainsKey(id))
{
node = (emailConfigHandler.mailNode)mailNodes[id];
}
else
{
Console.WriteLine("Invalid mail node ID!!! Check your configuration and try again.");
Environment.Exit(1);
}
string from = node.From;
string subject = node.Subject;
string body = node.Body;
ArrayList tolist = node.To;
string smtp = node.smtpserver;
and finally a few changes to the config file to add this data in it: