File: System\Configuration\AppSettingsSection.cs
Web Access
Project: src\src\libraries\System.Configuration.ConfigurationManager\src\System.Configuration.ConfigurationManager.csproj (System.Configuration.ConfigurationManager)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Collections.Specialized;
using System.IO;
using System.Xml;
 
namespace System.Configuration
{
    public sealed class AppSettingsSection : ConfigurationSection
    {
        private static volatile ConfigurationPropertyCollection s_properties;
        private static volatile ConfigurationProperty s_propAppSettings;
        private static volatile ConfigurationProperty s_propFile;
 
        private KeyValueInternalCollection _keyValueCollection;
 
        public AppSettingsSection()
        {
            EnsureStaticPropertyBag();
        }
 
        protected internal override ConfigurationPropertyCollection Properties => EnsureStaticPropertyBag();
 
        internal NameValueCollection InternalSettings
            => _keyValueCollection ??= new KeyValueInternalCollection(this);
 
        [ConfigurationProperty("", IsDefaultCollection = true)]
        public KeyValueConfigurationCollection Settings => (KeyValueConfigurationCollection)base[s_propAppSettings];
 
        [ConfigurationProperty("file", DefaultValue = "")]
        public string File
        {
            get
            {
                string fileValue = (string)base[s_propFile];
                return fileValue ?? string.Empty;
            }
            set { base[s_propFile] = value; }
        }
 
        private static ConfigurationPropertyCollection EnsureStaticPropertyBag()
        {
            if (s_properties != null) return s_properties;
 
            ConfigurationProperty propAppSettings = new ConfigurationProperty(
                name: null,
                type: typeof(KeyValueConfigurationCollection),
                defaultValue: null,
                options: ConfigurationPropertyOptions.IsDefaultCollection);
 
            ConfigurationProperty propFile = new ConfigurationProperty(
                name: "file",
                type: typeof(string),
                defaultValue: string.Empty,
                options: ConfigurationPropertyOptions.None);
 
            ConfigurationPropertyCollection properties = new ConfigurationPropertyCollection
            {
                propAppSettings,
                propFile
            };
 
            s_propAppSettings = propAppSettings;
            s_propFile = propFile;
            s_properties = properties;
 
            return s_properties;
        }
 
        protected internal override object GetRuntimeObject()
        {
            SetReadOnly();
            return InternalSettings; // return the read only object
        }
 
        protected internal override void Reset(ConfigurationElement parentSection)
        {
            _keyValueCollection = null;
            base.Reset(parentSection);
            if (!string.IsNullOrEmpty((string)base[s_propFile]))
            {
                // don't inherit from the parent by ignoring locks
                SetPropertyValue(prop: s_propFile, value: null, ignoreLocks: true);
            }
        }
 
        protected internal override void DeserializeElement(XmlReader reader, bool serializeCollectionKey)
        {
            string elementName = reader.Name;
 
            base.DeserializeElement(reader, serializeCollectionKey);
            if (!(File?.Length > 0)) return;
 
            string sourceFileFullPath;
 
            // Determine file location
            string configFile = ElementInformation.Source;
 
            sourceFileFullPath = string.IsNullOrEmpty(configFile)
                ? File
                : Path.Combine(Path.GetDirectoryName(configFile), File);
 
            if (!IO.File.Exists(sourceFileFullPath)) return;
            int lineOffset;
            string rawXml;
 
            using (Stream sourceFileStream = new FileStream(sourceFileFullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
            using (XmlUtil xmlUtil = new XmlUtil(sourceFileStream, sourceFileFullPath, true))
            {
                if (xmlUtil.Reader.Name != elementName)
                    throw new ConfigurationErrorsException(
                        SR.Format(SR.Config_name_value_file_section_file_invalid_root, elementName),
                        xmlUtil);
 
                lineOffset = xmlUtil.Reader.LineNumber;
                rawXml = xmlUtil.CopySection();
 
                // Detect if there is any XML left over after the section
                while (!xmlUtil.Reader.EOF)
                {
                    XmlNodeType t = xmlUtil.Reader.NodeType;
                    if (t != XmlNodeType.Comment)
                        throw new ConfigurationErrorsException(SR.Config_source_file_format, xmlUtil);
 
                    xmlUtil.Reader.Read();
                }
            }
 
            using ConfigXmlReader internalReader = new ConfigXmlReader(rawXml, sourceFileFullPath, lineOffset);
            internalReader.Read();
 
            if (internalReader.MoveToNextAttribute())
                throw new ConfigurationErrorsException(
                    SR.Format(SR.Config_base_unrecognized_attribute, internalReader.Name),
                    (XmlReader)internalReader);
 
            internalReader.MoveToElement();
 
            base.DeserializeElement(internalReader, serializeCollectionKey);
        }
    }
}