/// <summary>
        /// Gets the handler for a config section
        /// </summary>
        /// <param name="sectionName">Name of the handler</param>
        /// <param name="parentHandler">Handler of the parent section</param>
        /// <param name="xmlDoc">XML document containing the config</param>
        /// <returns>Handler for a config section</returns>
        private static object GetAppSettingsFileHandler(string sectionName, IConfigurationSectionHandler parentHandler, XmlDocument xmlDoc)
        {
            object       handler = null;
            XmlNode      node    = xmlDoc.SelectSingleNode("//" + sectionName);
            XmlAttribute att     = (XmlAttribute)node.Attributes.RemoveNamedItem("file");

            if (att == null || att.Value == null || att.Value.Length == 0)
            {
                return(parentHandler.Create(null, null, node));
            }
            else
            {
                string      fileName = att.Value;
                string      dir      = Path.GetDirectoryName(fileName);
                string      fullName = Path.Combine(dir, fileName);
                XmlDocument xmlDoc2  = new XmlDocument();
                xmlDoc2.Load(fullName);

                object parent = parentHandler.Create(null, null, node);
                IConfigurationSectionHandler h = new NameValueSectionHandler();
                handler = h.Create(parent, null, xmlDoc2.DocumentElement);
            }

            return(handler);
        }
예제 #2
0
        private object EvaluateRecursive(IConfigurationSectionHandler sectionHandler, object config, string[] keys, int keyIndex, XmlTextReader reader)
        {
            string name  = keys[keyIndex];
            int    depth = reader.Depth;

            while (reader.Read() && reader.NodeType != XmlNodeType.Element)
            {
                ;
            }
            while (reader.Depth == depth + 1)
            {
                if (reader.Name == name)
                {
                    if (keyIndex < keys.Length - 1)
                    {
                        config = EvaluateRecursive(sectionHandler, config, keys, keyIndex + 1, reader);
                    }
                    else
                    {
                        XmlDocument doc     = new XmlDocument();
                        XmlNode     section = doc.ReadNode(reader);
                        config = sectionHandler.Create(config, null, section);
                    }
                    continue;
                }
                SkipToNextElement(reader);
            }
            return(config);
        }
예제 #3
0
        public static object ReadSection(Configuration conf, string sectionname)
        {
            ConfigurationSection section = null;

            if (conf == null || (section = conf.GetSection(sectionname)) == null)
            {
                return(null);
            }

            string xml  = section.SectionInformation.GetRawXml();
            Type   type = Type.GetType(section.SectionInformation.Type);

            if (typeof(IConfigurationSectionHandler).IsAssignableFrom(type))
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(XmlReader.Create(new StringReader(xml)));

                IConfigurationSectionHandler configSectionHandlerHandle = Activator.CreateInstance(type) as IConfigurationSectionHandler;
                if (configSectionHandlerHandle != null)
                {
                    return(configSectionHandlerHandle.Create(null, null, doc));
                }
            }
            return(xml);
        }
예제 #4
0
        object GetConfigInternal(string sectionName, HttpContext context, bool useLoc)
        {
            object handler = GetHandler(sectionName);
            IConfigurationSectionHandler iconf = handler as IConfigurationSectionHandler;

            if (iconf == null)
            {
                return(handler);
            }

            object parentConfig = null;

            if (parent != null)
            {
                if (useLoc)
                {
                    parentConfig = parent.GetConfig(sectionName, context);
                }
                else
                {
                    parentConfig = parent.GetConfigOptLocation(sectionName, context, false);
                }
            }

            XmlDocument doc = GetDocumentForSection(sectionName);

            if (doc == null || doc.DocumentElement == null)
            {
                return(parentConfig);
            }

            return(iconf.Create(parentConfig, fileName, doc.DocumentElement));
        }
예제 #5
0
        /// <summary>
        /// Reads the specified configuration section from the given <see cref="XmlDocument"/>
        /// </summary>
        /// <param name="document"></param>
        /// <param name="configSectionName"></param>
        /// <param name="defaultConfigurationSectionHandlerType"></param>
        /// <returns></returns>
        public static object GetSectionFromXmlDocument(XmlDocument document, string configSectionName, Type defaultConfigurationSectionHandlerType)
        {
            Type handlerType = GetSectionHandlerType(document, configSectionName, defaultConfigurationSectionHandlerType);

            // obtain Xml node with section content
            XmlNode sectionContent = document.SelectSingleNode(string.Format("//{0}/{1}", ConfigurationElement, configSectionName));

            if (sectionContent == null)
            {
                // TODO: review if we shouldn't better simply return null here to match the ConfigurationManager's behaviour?
                throw ConfigurationUtils.CreateConfigurationException("Cannot read config section '" + configSectionName + "' - section not found.");
            }

            // IConfigurationSectionHandler
            if (typeof(IConfigurationSectionHandler).IsAssignableFrom(handlerType))
            {
                IConfigurationSectionHandler handler = (IConfigurationSectionHandler)ObjectUtils.InstantiateType(handlerType);
                return(handler.Create(null, null, sectionContent));
            }

            // NET 2.0 ConfigurationSection
            if (typeof(ConfigurationSection).IsAssignableFrom(handlerType))
            {
                ConfigurationSection section = CreateConfigurationSection(handlerType, new XmlNodeReader(sectionContent));
                return(section);
            }

            // Not supported
            throw ConfigurationUtils.CreateConfigurationException("Configuration section '" + configSectionName + "' is neither of type IConfigurationSectionHandler nor ConfigurationSection.");
        }
예제 #6
0
        object GetConfigInternal(string sectionName)
        {
            object handler = GetHandler(sectionName);
            IConfigurationSectionHandler iconf = handler as IConfigurationSectionHandler;

            if (iconf == null)
            {
                return(handler);
            }

            object parentConfig = null;

            if (parent != null)
            {
                parentConfig = parent.GetConfig(sectionName);
            }

            XmlDocument doc = GetDocumentForSection(sectionName);

            if (doc == null || doc.DocumentElement == null)
            {
                return(parentConfig);
            }

            return(iconf.Create(parentConfig, fileName, doc.DocumentElement));
        }
예제 #7
0
            internal object CreateSection(bool inputIsTrusted, RuntimeConfigurationRecord configRecord,
                                          FactoryRecord factoryRecord, SectionRecord sectionRecord, object parentConfig, ConfigXmlReader reader)
            {
                object config;

                if (_sectionCtor != null)
                {
                    ConfigurationSection configSection =
                        (ConfigurationSection)_sectionCtor.Invoke(null);

                    configSection.SectionInformation.SetRuntimeConfigurationInformation(configRecord, factoryRecord,
                                                                                        sectionRecord);

                    configSection.CallInit();

                    ConfigurationSection parentSection = (ConfigurationSection)parentConfig;
                    configSection.Reset(parentSection);

                    if (reader != null)
                    {
                        configSection.DeserializeSection(reader);
                    }

                    // throw if there are any cached errors
                    ConfigurationErrorsException errors = configSection.GetErrors();
                    if (errors != null)
                    {
                        throw errors;
                    }

                    // don't allow changes to sections at runtime
                    configSection.SetReadOnly();

                    // reset the modified bit
                    configSection.ResetModified();

                    config = configSection;
                }
                else
                {
                    if (reader != null)
                    {
                        XmlNode xmlNode = ErrorInfoXmlDocument.CreateSectionXmlNode(reader);

                        CheckForLockAttributes(factoryRecord.ConfigKey, xmlNode);

                        // In v1, our old section handler expects a context that contains the virtualPath from the configPath
                        object configContext = configRecord.Host.CreateDeprecatedConfigContext(configRecord.ConfigPath);

                        config = _sectionHandler.Create(parentConfig, configContext, xmlNode);
                    }
                    else
                    {
                        config = null;
                    }
                }

                return(config);
            }
예제 #8
0
        private object EvaluateRecursive(IConfigurationSectionHandler factory, object config, string [] keys, int iKey, XmlTextReader reader)
        {
            string name = keys[iKey];

            TraceVerbose("  EvaluateRecursive " + iKey + " " + name);

            int depth = reader.Depth;

            while (reader.Read() && reader.NodeType != XmlNodeType.Element)
            {
                ;
            }

            while (reader.Depth == depth + 1)
            {
                TraceVerbose("  EvaluateRecursive " + iKey + " " + name + " Name:" + reader.Name);
                if (reader.Name == name)
                {
                    if (iKey < keys.Length - 1)
                    {
                        config = EvaluateRecursive(factory, config, keys, iKey + 1, reader);
                    }
                    else
                    {
                        TraceVerbose("  EvaluateRecursive " + iKey + " calling Create()");
                        Debug.Assert(iKey == keys.Length - 1);

                        //
                        // Call configuration section handler
                        //
                        // - try-catch is necessary to insulate config system from exceptions in user config handlers.
                        //   - bubble ConfigurationExceptions & XmlException
                        //   - wrap all others in ConfigurationException
                        //
                        int line = reader.LineNumber;
                        try {
                            ConfigXmlDocument doc = new ConfigXmlDocument();
                            doc.LoadSingleElement(_filename, reader);
                            config = factory.Create(config, null, doc.DocumentElement);
                        }
                        catch (ConfigurationException) {
                            throw;
                        }
                        catch (XmlException) {
                            throw;
                        }
                        catch (Exception ex) {
                            throw new ConfigurationException(
                                      SR.GetString(SR.Exception_in_config_section_handler),
                                      ex, _filename, line);
                        }
                    }
                    continue;
                }
                StrictSkipToNextElement(reader);
            }
            return(config);
        }
예제 #9
0
        public static T OpenCreate <T>(this IConfigurationSectionHandler <T> configurationLocation)
        {
            if (!configurationLocation.Exists())
            {
                return(configurationLocation.Create());
            }

            return(configurationLocation.Open());
        }
예제 #10
0
        ///<summary>
        ///Creates a configuration section.
        ///</summary>
        ///
        ///<returns>
        ///The created section object.
        ///</returns>
        ///
        ///<param name="parent">Parent object.</param>
        ///<param name="section">Section XML node.</param>
        ///<param name="configContext">Configuration context object.</param><filterpriority>2</filterpriority>
        public object Create(object parent, object configContext, XmlNode section)
        {
            if (s_callback != null)
            {
                return(s_callback(parent, configContext, section));
            }

            return(baseHandler.Create(parent, configContext, section));
        }
        public object Create(object parent, object configContext, XmlNode section)
        {
            Type configReaderBaseType = Type.GetType(((XmlElement)section)?.GetAttribute("configReaderBaseType"));

            ValidateBaseType(configReaderBaseType);

            BaseConfig = CreateDynamicConfigReader(configReaderBaseType);

            return(BaseConfig.Create(parent, configContext, section));
        }
예제 #12
0
        private object EvaluateRecursive(IConfigurationSectionHandler factory, object config, string[] keys, int iKey, XmlTextReader reader, object context)
        {
            string name  = keys[iKey];
            int    depth = reader.Depth;

            while (reader.Read() && reader.NodeType != XmlNodeType.Element)
            {
                ;
            }

            while (reader.Depth == depth + 1)
            {
                if (reader.Name == name)
                {
                    if (iKey < keys.Length - 1)
                    {
                        config = EvaluateRecursive(factory, config, keys, iKey + 1, reader, context);
                    }
                    else
                    {
                        // Call configuration section handler
                        int line = reader.LineNumber;

                        // Try-catch is necessary to protect from exceptions in user config handlers
                        try
                        {
                            ConfigXmlDocument doc = new ConfigXmlDocument();
                            doc.LoadSingleElement(filename, reader);
                            config = factory.Create(config, context, doc.DocumentElement);
                        }
                        catch (ConfigurationException)
                        {
                            // Bubble ConfigurationExceptions
                            throw;
                        }
                        catch (XmlException)
                        {
                            // Bubble XmlExceptions
                            throw;
                        }
                        catch (Exception ex)
                        {
                            // Wrap all others as ConfigurationExceptions
                            throw new ConfigurationException("Exception in ConfigSectionHandler", ex, filename, line);
                        }
                    }
                    continue;
                }
                StrictSkipToNextElement(reader);
            }
            return(config);
        }
예제 #13
0
        object IConfigurationSectionHandler.Create(object parent, object configContext, XmlNode section)
        {
            XmlDocument document  = (XmlDocument)section.ParentNode;
            XmlNode     fixedNode = document.CreateElement("hibernate-configuration");

            section.ParentNode.ReplaceChild(fixedNode, section);

            foreach (XmlNode node in section.ChildNodes)
            {
                fixedNode.AppendChild(section.RemoveChild(node));
            }
            return(_originalHandler.Create(parent, configContext, fixedNode));
        }
        /// <summary>
        /// Reads a section from the configuration file.
        /// </summary>
        /// <param name="sectionName">The name of the section in the configuration file.</param>
        /// <returns>A deserialized configuration object.</returns>
        public static object GetSection(string sectionName)
        {
            if (!HasConfiguration)
            {
                return(null);
            }
            if (string.IsNullOrEmpty(sectionName))
            {
                return(null);
            }
            if (Sections.ContainsKey(sectionName))
            {
                return(Sections[sectionName]);
            }

            var sectionNode = GetSectionNode(sectionName);

            if (sectionNode == null)
            {
                return(null);
            }

            Section section = (from s in ConfigSections
                               where s.Name == sectionName
                               select s).FirstOrDefault();

            if (section == null)
            {
                return(null);
            }
            var sectionHandlerType = Type.GetType(section.Type, false, true);

            if (sectionHandlerType == null)
            {
                throw new ConfigurationErrorsException(string.Format(
                                                           "Section {0} has an invalid section handler type.",
                                                           sectionName));
            }
            if (!typeof(IConfigurationSectionHandler).IsAssignableFrom(sectionHandlerType))
            {
                throw new ConfigurationErrorsException(string.Format(
                                                           "Type {0} does not implement IConfigurationSectionHandler",
                                                           sectionHandlerType.FullName));
            }

            IConfigurationSectionHandler handler = (IConfigurationSectionHandler)Activator.CreateInstance(sectionHandlerType);
            var conf = handler.Create(null, null, sectionNode);

            Sections[sectionName] = conf;
            return(conf);
        }
예제 #15
0
        private static StatsSettings GetSettings(string filename)
        {
            try
            {
                var filepath = filename;
                if (!Path.IsPathRooted(filename))
                {
                    Assembly ass = Assembly.GetCallingAssembly();

                    filepath = Path.Combine(Path.GetDirectoryName(ass.Location), filename);
                }

                if (!File.Exists(filepath))
                {
                    return(null);
                }

                var fileMap = new ExeConfigurationFileMap {
                    ExeConfigFilename = filepath
                };
                var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

                ConfigurationSection section = section = configuration.GetSection("StatsSettings");
                if (section == null)
                {
                    return(null);
                }

                string xml  = section.SectionInformation.GetRawXml();
                Type   type = Type.GetType(section.SectionInformation.Type);

                if (typeof(IConfigurationSectionHandler).IsAssignableFrom(type))
                {
                    XmlDocument doc = new XmlDocument();
                    doc.Load(XmlReader.Create(new StringReader(xml)));

                    IConfigurationSectionHandler configSectionHandlerHandle = Activator.CreateInstance(type) as IConfigurationSectionHandler;
                    if (configSectionHandlerHandle != null)
                    {
                        return(configSectionHandlerHandle.Create(null, null, doc) as StatsSettings);
                    }
                }
            }
            catch { }

            return(null);
        }
예제 #16
0
        /// <summary>
        /// Create the concrete object using the information found in the specified section name.  Mimicks the IConfigurationSectionHandler.Create method.
        /// </summary>
        /// <param name="sectionName">Name of the section.</param>
        /// <returns>object which should cast to the correct type</returns>
        public object Create(string sectionName)
        {
            XmlNode xn = this.GetSectionMetaData(sectionName);

            if (null == xn)
            {
                throw new ApplicationException(string.Format("The file {0} did not contain the section '{1}'", this._path, sectionName));
            }

            XmlElement root = (XmlElement)xn;

            string name = string.Empty;
            string type = string.Empty;

            string currentXpath = "name";

            //this name should always be the same as the SectionName, but this makes sure I guess.  You can comment it out if you'd like.
            name = root.Attributes[currentXpath].Value;

            currentXpath = "type";
            type         = root.Attributes[currentXpath].Value;

            //create an array, with the ";" delimiter
            string[] typeValues = type.Split(',');

            if (null == typeValues || typeValues.Length != 2)
            {
                throw new ApplicationException(string.Format("The type attibute should contain 2 items seperated by a comma.  The invalid value is {0}.", type));
            }

            string assemblyName = typeValues[1];
            string className    = typeValues[0];

            IConfigurationSectionHandler icsh = this.CreateHandler(className, assemblyName);

            XmlNode sectionNode = this.GetSection(name);

            object returnObject = icsh.Create(this, this, sectionNode);

            return(returnObject);
        }
        /// <summary>
        /// Gets the config.
        /// </summary>
        /// <param name="sectionName">Name of the section.</param>
        /// <param name="configFileName">Name of the config file.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public static object GetConfig(string sectionName, string configFileName)
        {
            var xmlDoc = new XmlDocument();

            xmlDoc.Load(configFileName);

            IConfigurationSectionHandler handler = GetHandler(sectionName, xmlDoc);
            object config = null;

            if (sectionName == APPSETTINGS_SECTION_NAME)
            {
                config = GetAppSettingsFileHandler(sectionName, handler, xmlDoc);
            }
            else
            {
                XmlNode node = xmlDoc.SelectSingleNode("//" + sectionName);
                config = handler.Create(null, null, node);
            }

            return(config);
        }
예제 #18
0
        /// <summary>
        /// Get the specified section
        /// </summary>
        /// <param name="contextName"></param>
        /// <param name="parent"></param>
        /// <param name="sectionName"></param>
        /// <returns></returns>
        public object GetSection(string contextName, object parent, string sectionName)
        {
            EnsureInit();
            ConfigurationSection thisSection = _configuration.GetSection(sectionName);

            //object parent = null;
            if (_next != null)
            {
                parent = _next.GetSection(sectionName);
            }
            if (thisSection == null)
            {
                return(parent);
            }

            object result = resolveSectionRuntimeObject(thisSection);

            if (result is DefaultSection)
            {
                string rawXml = thisSection.SectionInformation.GetRawXml();
                if (string.IsNullOrEmpty(rawXml))
                {
                    return(null);
                }

                Type t = TypeResolutionUtils.ResolveType(thisSection.SectionInformation.Type);
                //ContextHandler ch = new ContextHandler();
                if (typeof(IConfigurationSectionHandler).IsAssignableFrom(t))
                {
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.LoadXml(thisSection.SectionInformation.GetRawXml());
                    IConfigurationSectionHandler handler = (IConfigurationSectionHandler)Activator.CreateInstance(t);
                    return(handler.Create(parent, null, SetContextName(contextName, xmlDoc.DocumentElement)));
                }
                throw new ConfigurationErrorsException(string.Format(" <section>配置节点没有声明'{0}'", sectionName));
            }
            return(result);
        }
예제 #19
0
        private object EvaluateRecursive(IConfigurationSectionHandler factory, object config, string [] keys, int iKey, XmlTextReader reader) {
            string name = keys[iKey];
            TraceVerbose("  EvaluateRecursive " + iKey + " " + name);

            int depth = reader.Depth;

            while (reader.Read() && reader.NodeType != XmlNodeType.Element);

            while (reader.Depth == depth + 1) {
                TraceVerbose("  EvaluateRecursive " + iKey + " " + name + " Name:" + reader.Name);
                if (reader.Name == name) {
                    if (iKey < keys.Length - 1) {
                        config = EvaluateRecursive(factory, config, keys, iKey + 1, reader);
                    }
                    else {
                        TraceVerbose("  EvaluateRecursive " + iKey + " calling Create()");
                        Debug.Assert(iKey == keys.Length - 1);

                        // 
                        // Call configuration section handler
                        // 
                        // - try-catch is necessary to insulate config system from exceptions in user config handlers.
                        //   - bubble ConfigurationExceptions & XmlException
                        //   - wrap all others in ConfigurationException
                        //
                        int line = reader.LineNumber;
                        try {
                            ConfigXmlDocument doc = new ConfigXmlDocument();
                            doc.LoadSingleElement(_filename, reader);
                            config = factory.Create(config, null, doc.DocumentElement);
                        }
                        catch (ConfigurationException) {
                            throw;
                        }
                        catch (XmlException) {
                            throw;
                        }
                        catch (Exception ex) {
                            throw new ConfigurationException(
                                        SR.GetString(SR.Exception_in_config_section_handler),
                                        ex, _filename, line);
                        }

                    }
                    continue;
                }
                StrictSkipToNextElement(reader);
            }
            return config;
        }
        protected static object GetAppSettingsFileHandler(string sectionName, IConfigurationSectionHandler parentHandler, XmlDocument xmlDoc)
        {
            object handler = null;
            XmlNode node = xmlDoc.SelectSingleNode("//" + sectionName);
            XmlAttribute att = (XmlAttribute)node.Attributes.RemoveNamedItem("file");

            if (att == null || att.Value == null || att.Value.Length == 0)
            {
                return parentHandler.Create(null, null, node);
            }
            else
            {
                string fileName = att.Value;
                string dir = Path.GetDirectoryName(fileName);
                string fullName = Path.Combine(dir, fileName);
                XmlDocument xmlDoc2 = new XmlDocument();
                xmlDoc2.Load(fullName);

                object parent = parentHandler.Create(null, null, node);
                IConfigurationSectionHandler h = new NameValueSectionHandler();
                handler = h.Create(parent, null, xmlDoc2.DocumentElement);
            }

            return handler;
        }
예제 #21
0
 private object EvaluateRecursive(IConfigurationSectionHandler sectionHandler, object config, string[] keys, int keyIndex, XmlTextReader reader)
 {
     string name = keys[keyIndex];
     int depth = reader.Depth;
     while (reader.Read() && reader.NodeType != XmlNodeType.Element)
     {
         ;
     }
     while (reader.Depth == depth + 1)
     {
         if (reader.Name == name)
         {
             if (keyIndex < keys.Length - 1)
             {
                 config = EvaluateRecursive(sectionHandler, config, keys, keyIndex + 1, reader);
             }
             else
             {
                 XmlDocument doc = new XmlDocument();
                 XmlNode section = doc.ReadNode(reader);
                 config = sectionHandler.Create(config, null, section);
             }
             continue;
         }
         SkipToNextElement(reader);
     }
     return config;
 }
		// Get the object for a specific configuration key and handler.
		public Object GetConfig
					(String configKey, IConfigurationSectionHandler handler)
				{
				#if SECOND_PASS
					// Bail out if the configuration key is invalid.
					if(configKey == null || configKey.Length == 0)
					{
						return null;
					}

					// See if we have cached information from last time.
					if(cachedInfo.Contains(configKey))
					{
						return cachedInfo[configKey];
					}

					// Get the section handler, if necessary.
					if(handler == null)
					{
						Object schema = sectionSchema[configKey];
						if(schema == null)
						{
							// We don't know how to handle the section.
							cachedInfo[configKey] = null;
							return null;
						}
						else if(schema == groupMarker)
						{
							// This section is a group.
							cachedInfo[configKey] = null;
							return null;
						}
						else
						{
							// Create an instance of the specified handler.
							Type handlerType = Type.GetType((String)schema);
							if(handlerType == null)
							{
								cachedInfo[configKey] = null;
								return null;
							}
							handler = Activator.CreateInstance(handlerType)
										as IConfigurationSectionHandler;
							if(handler == null)
							{
								cachedInfo[configKey] = null;
								return null;
							}
						}
					}

					// Scan all documents, and collect up the data.
					Object data = null;
					int posn;
					XmlNode section;
					for(posn = 0; posn < numDocuments; ++posn)
					{
						section = FindSectionByName
							(documents[posn].DocumentElement, configKey);
						if(section != null)
						{
							data = handler.Create(data, null, section);
						}
					}

					// Cache the data for next time and then return it.
					cachedInfo[configKey] = data;
					return data;
				#else
					// Configuration data is not available, so bail out.
					return null;
				#endif
				}
예제 #23
0
            // Get the object for a specific configuration key and handler.
            public Object GetConfig
                (String configKey, IConfigurationSectionHandler handler)
            {
                                #if SECOND_PASS
                // Bail out if the configuration key is invalid.
                if (configKey == null || configKey.Length == 0)
                {
                    return(null);
                }

                // See if we have cached information from last time.
                if (cachedInfo.Contains(configKey))
                {
                    return(cachedInfo[configKey]);
                }

                // Get the section handler, if necessary.
                if (handler == null)
                {
                    Object schema = sectionSchema[configKey];
                    if (schema == null)
                    {
                        // We don't know how to handle the section.
                        cachedInfo[configKey] = null;
                        return(null);
                    }
                    else if (schema == groupMarker)
                    {
                        // This section is a group.
                        cachedInfo[configKey] = null;
                        return(null);
                    }
                    else
                    {
                        // Create an instance of the specified handler.
                        Type handlerType = Type.GetType((String)schema);
                        if (handlerType == null)
                        {
                            cachedInfo[configKey] = null;
                            return(null);
                        }
                        handler = Activator.CreateInstance(handlerType)
                                  as IConfigurationSectionHandler;
                        if (handler == null)
                        {
                            cachedInfo[configKey] = null;
                            return(null);
                        }
                    }
                }

                // Scan all documents, and collect up the data.
                Object  data = null;
                int     posn;
                XmlNode section;
                for (posn = 0; posn < numDocuments; ++posn)
                {
                    section = FindSectionByName
                                  (documents[posn].DocumentElement, configKey);
                    if (section != null)
                    {
                        data = handler.Create(data, null, section);
                    }
                }

                // Cache the data for next time and then return it.
                cachedInfo[configKey] = data;
                return(data);
                                #else
                // Configuration data is not available, so bail out.
                return(null);
                                #endif
            }
		private object EvaluateRecursive(IConfigurationSectionHandler factory, object config, string[] keys, int iKey, XmlTextReader reader)
		{
			string name = keys[iKey];
			int depth = reader.Depth;
			
			while(reader.Read() && reader.NodeType != XmlNodeType.Element);

			while (reader.Depth == depth + 1)
			{
				if (reader.Name == name)
				{
					if (iKey < keys.Length - 1)
					{
						config = EvaluateRecursive(factory, config, keys, iKey + 1, reader);
					}
					else 
					{
						// Call configuration section handler
						int line = reader.LineNumber;

						// Try-catch is necessary to protect from exceptions in user config handlers
						try
						{
							ConfigXmlDocument doc = new ConfigXmlDocument();
							doc.LoadSingleElement(filename, reader);
							config = factory.Create(config, null, doc.DocumentElement);
						}
						catch(ConfigurationException)
						{
							// Bubble ConfigurationExceptions
							throw;
						}
						catch (XmlException)
						{
							// Bubble XmlExceptions
							throw;
						}
						catch(Exception ex)
						{
							// Wrap all others as ConfigurationExceptions
							throw new ConfigurationException("Exception in ConfigSectionHandler", ex, filename, line);
						}
					}
					continue;
				}
				StrictSkipToNextElement(reader);
			}
			return config;
		}