Page 1 of 1

Read config file in Class Library

#1 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1641
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Post icon  Posted 26 November 2007 - 06:59 AM

Ever written a Library Class, in either VB.Net or in C#, and realized that your class will always read the configuration file for the application itself, not the class, I don't about you but I found this to be quite frustrating. Through several hours, use several lightly I foud I could use Reflecion, XML, System.Configuration, and Collections to write a class library that can read its own configuration from withint whatever application its being called from.

First thing we need to in our Library Class is, of course, add our Namespace's, and I believe I did a good job above showing the namespaces we will be needing:

using System;
using System.Reflection;
using System.Collections;
using System.Xml;
using System.Configuration;



Next we will need to global variables, one that will hold the key/value pairs from our configuration file, and the second to hold the name of the node we are looking for in our XML document:

/// <summary>
/// settings to be used throughout the class
/// </summary>
private IDictionary settings;
/// <summary>
/// constant name for the node name we're looking for
/// </summary>
const string nodeName = "assemblySettings";



Next, as with any class we want to instantiate, we need a Constructor. Our single constructor accepts a single parameter, the Assembly to read the configuration file for:

/// <summary>
/// constructor that sets the value of our "settings" variable
/// </summary>
/// <param name="asm">Name of the assembly calling</param>
public PCReader(Assembly asm)
{
	settings = GetConfig(asm);
}



Next in our class we need an Indexer, in C# an Indexer is just another way of defining properties. The Indexer would give us acces to all the properties of a class like would be used in VB.Net:

/// <summary>
/// empty constructor
/// </summary>
public ConfigReader()
	: this(Assembly.GetCallingAssembly())
{
}




/// <summary>
/// class Indexer, this gives us
/// access to all properties of this
/// class, same as properties in VB.Net
/// </summary>
public string this[string key]
{
	get
	{
		string settingValue = null;

		if(settings != null)
		{
			settingValue = settings[key] as string;
		}

		return(settingValue == null ? "" : settingValue);
	}
}



Now we get into the meat of our config file reader. Here we have 2 methods left, and will be using Method Overloading, since methods are essentially the same, but are also different. We'll look at the first methos, this is called ReadConfig:

/// <summary>
/// Method to open and parse the config
/// file for this assembly only
/// </summary>
/// <returns></returns>
public static IDictionary ReadConfig()
{
	return ReadConfig(Assembly.GetCallingAssembly());
}



The next version of ReadConfig is actually the version the shorter version of ReadConfig calls to populate the properties and indexes of our configuration fall, as you can imagine, this one is quite longer:

/// <summary>
/// method to open and parse the config
/// file for the provided assembly
/// </summary>
/// <param name="asm">Assembly's config file to parse</param>
/// <returns></returns>
public static IDictionary ReadConfig(Assembly asm)
{			
	try
	{
		//string to hold the name of the 
		//config file for the assembly
		string cfgFile = asm.CodeBase + ".config";
		
		//create a new XML Document
		XmlDocument doc = new XmlDocument();
		//load an XML document by using the
		//XMLTextReader class of the XML Namespace
		//yo open the sfgFile
		doc.Load(new XmlTextReader(cfgFile));
		//retrieve a list of nodes in the document
		XmlNodeList nodes = doc.GetElementsByTagName(nodeName);
		//now we need to loop through all the
		//nodes in the XML document
		foreach( XmlNode node in nodes )
		{
			//now check to see if the name of the node
			//in this iteration is the same as our global
			//nodeName variable
			if( node.LocalName == nodeName )
			{
				//since they match we need to use the
				//DictionarySectionHandler and create a
				//new handler and add it to the collection
				DictionarySectionHandler handler = new DictionarySectionHandler();
				//rerutn the new handler
				return (IDictionary)handler.Create(null, null, node);
			}
		}
	}
	catch(Exception e)
	{
		System.Diagnostics.Debug.WriteLine(e.Message);
	}

	return(null);
}


So that my friends is how you would read a Class Libraries configuration file. Remember, in your XML configuration file the node that holds your settings has to be named "asmSettings" of the class wont recognize the settings in the file. I hope you found this tutorial informative and useful, and as alaways thank you for reading.

Happy Coding :)

This post has been edited by PsychoCoder: 27 November 2007 - 03:01 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Read config file in Class Library

#2 Guest_Guest*


Reputation:

Posted 17 September 2010 - 07:06 AM

Great example! I modified your example for people interested in getting the config settings of the executable. I used xpath to get the specific node and derived the class from Dictionary<string, string> to allow for common indexing operations.

/
// <summary>
    /// This helper class allows heler libraries access to their executable consumers' configuration settings
    /// </summary>
    public class AppConfigurationhelper : Dictionary<string, string>
    {
        private IDictionary settings;

        const string appConfigNodeName = "appSettings";

        // We are interested in the executing assembly, not the calling assembly since this class will be used by another class in this helper helper assembly
        public AppConfigurationhelper() : this(Assembly.GetEntryAssembly())  
        {  

        } 



        public AppConfigurationhelper(Assembly consumingAssembly)
        {
            
            ReadConfig(consumingAssembly);
        }


        


        public void ReadConfig()
        {  

            ReadConfig(Assembly.GetEntryAssembly());  

        } 

        /// <summary>  

        /// method to open and parse the config  

        /// file for the provided assembly  
       
        /// </summary>  

        /// <param name="asm">Assembly's config file to parse</param>  

        /// <returns></returns>  

        public void ReadConfig(Assembly asm)  

        {             

            try  

            {  

                //string to hold the name of the   

                //config file for the assembly  

                string cfgFile = asm.CodeBase + ".config";  



                //create a new XML Document  

                XmlDocument doc = new XmlDocument();  

                //load an XML document by using the  

                //XMLTextReader class of the XML Namespace  

                //Now open the cfgFile  

                doc.Load(new XmlTextReader(cfgFile));  

                //retrieve a list of nodes in the document  



                XmlNode configNode = doc.SelectSingleNode(string.Format("//{0}", appConfigNodeName));
                if (configNode != null)
                {
                    DictionarySectionHandler handler = new DictionarySectionHandler();

                    //return the new handler  

                    IDictionary configSection = (IDictionary)handler.Create(null, null, configNode);
                    foreach (string key in configSection.Keys)
                    {
                        this.Add(key, (string)configSection[key]);
                    }


                }



            }  
            catch(Exception e)  
            {  

                System.Diagnostics.Debug.WriteLine(e.Message);  

            }  



                

            }



      
    }

Was This Post Helpful? 0

Page 1 of 1