Ver Fonte

ConfigurationSettings.cs: No longer references the NameValueSectionHandler directly. Instead it uses System.Reflection to call the Create() method for the appropriate SectionHandler as defined in the .config file.

svn path=/trunk/mcs/; revision=627
Christopher Podurgiel há 24 anos atrás
pai
commit
3fbbb1ed80

+ 5 - 0
mcs/class/System/System.Configuration/ChangeLog

@@ -0,0 +1,5 @@
+2001-08-26  Christopher Podurgiel <[email protected]>
+
+	* ConfigurationSettings.cs: No longer references the NameValueSectionHandler directly.  Instead
+	  it uses System.Reflection to call the Create() method for the appropriate SectionHandler as defined in the .config file.
+

+ 109 - 28
mcs/class/System/System.Configuration/ConfigurationSettings.cs

@@ -4,12 +4,12 @@
 // Author:
 //   Christopher Podurgiel ([email protected])
 //
-// (C) Ximian, Inc.  http://www.ximian.com
+// C) Christopher Podurgiel
 //
 
 using System;
-using System.Collections;
 using System.Collections.Specialized;
+using System.Reflection;
 using System.Xml;
 using System.Xml.XPath;
 using System.Windows.Forms;
@@ -26,7 +26,6 @@ namespace System.Configuration
 	public sealed class ConfigurationSettings
 	{
 
-		static NameValueCollection _nvcAppSettings;
 		private static string applicationConfigFileName;
 		
 		/// <summary>
@@ -40,16 +39,13 @@ namespace System.Configuration
 		/// <summary>
 		///		Returns configuration settings for a user-defined configuration section.
 		/// </summary>
-		/// <param name="sectionName"></param>
+		/// <param name="sectionName">The name of the configuration section that configuration settings are read from.</param>
 		/// <returns></returns>
 		public static object GetConfig(string sectionName)
 		{
 			//Create an instance of an XML Document.
 			XmlDocument ConfigurationDocument = new XmlDocument();
-			XmlNode sectionNode;
 
-
-			
 			/*
 			 * LAMESPEC: The .config file that needs to be parsed is the name of the application, plus ".config"
 			 * ie. "Myapplication.exe.config"
@@ -59,53 +55,138 @@ namespace System.Configuration
 			*/
 			//Get the full path to the Applicaton Configuration File.
 			applicationConfigFileName = Application.ExecutablePath + ".config";
-			
-			//Create a new NameValueSectionHandler
-			NameValueSectionHandler objNVSHandler = new NameValueSectionHandler();
 
 			//Try to load the XML Document.
 			try
 			{ 
 				ConfigurationDocument.Load(applicationConfigFileName);
-				sectionNode = ConfigurationDocument.SelectSingleNode("//" + sectionName);
 			}
-			catch(XmlException)
+			catch(XmlException e)
 			{
-				//If an XmlException is thrown, it probably means that the .config file we are trying to load doesn't exist.
-				return null;
-			}
-			catch(XPathException)
-			{	
-				//An XPathException is thrown if there was a problem with our XPath statement.
-				return null;	
+				//Error loading the XML Document.  Throw a ConfigurationException.
+				throw(new ConfigurationException(e.Message, applicationConfigFileName, e.LineNumber));
 			}
+
+				string sectionHandlerName = GetSectionHanderType(ConfigurationDocument, sectionName);
+			     
+				XmlNode sectionNode = ConfigurationDocument.SelectSingleNode("/configuration/" + sectionName);
+			
 			
-			//If the specified sectionName is not found, then sectionNode will be null, and we can't pass
-			// a null to objNVSHandler.Create()
+			
+			//If the specified sectionName is not found, then sectionNode will be null.  When calling objNVSHandler.Create(),
+			//sectionNode cannot be null.
 			 if(sectionNode == null)
 			{
 				return null;
 			}
 			
-			//Create a NameValueSecitonHandler and add it to the NameValueCollection
-			object readOnlyNVCollection = objNVSHandler.Create(null, null, sectionNode);
 
+			//Create a new SectionHandler
+
+			//According to the Docs provided by Microsoft, the user can create their own configuration sections, and create a custom
+			//handler class for it. The user would specify the class and its assebly in the <configSections> section.  These would be
+			//seperated by a comma.
+
+			string sectionHandlerClassName = sectionHandlerName;
+			string sectionHandlerAssemblyName = "System";
+
+			//Split the SectionHandler Class Name from the Assembly Name (if provided).
+			string[] sectionHandlerArray = sectionHandlerName.Split(new char[]{','}, 2);
+			if(sectionHandlerArray.Length == 2)
+			{
+				sectionHandlerClassName = sectionHandlerArray[0];
+				sectionHandlerAssemblyName = sectionHandlerArray[1];
+			}
 			
+			// Load the assembly to use.
+			Assembly assem = Assembly.Load(sectionHandlerAssemblyName);
+			//Get the class type.
+			Type handlerObjectType = assem.GetType(sectionHandlerClassName);
+			//Get a reference to the method "Create"
+			MethodInfo createMethod = handlerObjectType.GetMethod("Create");
+			//Create an Instance of this SectionHandler.
+			Object objSectionHandler = Activator.CreateInstance(handlerObjectType);
+
+			//define the arguments to be passed to the "Create" Method.
+			Object[] args = new Object[3];
+			args[0] = null;
+			args[1] = null;
+			args[2] = sectionNode;
+
+			object sectionHandlerCollection = createMethod.Invoke(objSectionHandler, args);
+
 			//Return the collection
-			return readOnlyNVCollection;
+			return sectionHandlerCollection;
+
+		}
+
+
+		/// <summary>
+		///		Gets the name of the SectionHander Class that will handle this section.
+		/// </summary>
+		/// <param name="xmlDoc">An xml Configuration Document.</param>
+		/// <param name="sectionName">The name of the configuration section that configuration settings are read from.</param>
+		/// <returns>The name of the Handler Object for this configuration section, including the name if its Assembly.</returns>
+		private static string GetSectionHanderType(XmlDocument xmlDoc, string sectionName)
+		{
+			//TODO: This method does not account for sectionGroups yet.
+			string handlerName = null;
+
+			//<appSettings> is a predefined configuration section. It does not have a definition
+			// in the <configSections> section, and will always be handled by the NameValueSectionHandler.
+			if(sectionName == "appSettings")
+			{
+				handlerName = "System.Configuration.NameValueSectionHandler";
+			}
+			else
+			{
+				
+				string[] sectionPathArray = sectionName.Split(new char[]{'/'});
+
+				//Build an XPath statement.
+				string xpathStatement = "/configuration/configSections";
+				for (int i=0; i < sectionPathArray.Length; i++)
+				{
+					if(i < sectionPathArray.Length - 1)
+					{
+						xpathStatement = xpathStatement + "/sectionGroup[@name='" + sectionPathArray[i] + "']";
+					}
+					else
+					{
+						xpathStatement = xpathStatement + "/section[@name='" + sectionPathArray[i] + "']";
+					}
+				}
+				
+				//Get all of the <section> node using the xpath statement.
+				XmlNode sectionNode = xmlDoc.SelectSingleNode(xpathStatement);
+
+				// if this section isn't found, then there was something wrong with the config document,
+				// or the sectionName didn't have a proper definition.
+				if(sectionNode == null)
+				{
+					
+					throw (new ConfigurationException("Unrecognized element."));
+				}
+
+				handlerName =  sectionNode.Attributes["type"].Value;
+
+			}
+
+			//Return the name of the handler.
+			return handlerName;
 		}
 
+
+
 		/// <summary>
 		///		Get the Application Configuration Settings.
 		/// </summary>
 		public static NameValueCollection AppSettings
 		{
 			get
-			{	//Define appSettings as a NameValueCollection.
-				NameValueCollection appSettings;
-
+			{	
 				//Get the Configuration Settings for the "appSettings" section.
-				appSettings = (NameValueCollection) GetConfig("appSettings");;
+				NameValueCollection appSettings = (NameValueCollection)GetConfig("appSettings");;
 
 				return appSettings;
 			}