| File: System\Configuration\Configuration.cs | Web Access |
| Project: src\runtime\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; using System.Configuration.Internal; using System.IO; using System.Runtime.Versioning; namespace System.Configuration { // An instance of the Configuration class represents a single level // in the configuration hierarchy. Its contents can be edited and // saved to disk. // // It is not thread safe for writing. public sealed class Configuration { private readonly MgmtConfigurationRecord _configRecord; private readonly object[] _hostInitConfigurationParams; private readonly Type _typeConfigHost; private Func<string, string> _assemblyStringTransformer; private ContextInformation _evalContext; private ConfigurationLocationCollection _locations; private ConfigurationSectionGroup _rootSectionGroup; private Stack _sectionsStack; private Func<string, string> _typeStringTransformer; internal Configuration(string locationSubPath, Type typeConfigHost, params object[] hostInitConfigurationParams) { _typeConfigHost = typeConfigHost; _hostInitConfigurationParams = hostInitConfigurationParams; IInternalConfigHost configHost = (IInternalConfigHost)TypeUtil.CreateInstance(typeConfigHost); // Wrap the host with the UpdateConfigHost to support SaveAs. UpdateConfigHost updateConfigHost = new UpdateConfigHost(configHost); // Now wrap in ImplicitMachineConfigHost so we can stub in a simple machine.config if needed. ImplicitMachineConfigHost implicitMachineConfigHost = new ImplicitMachineConfigHost(updateConfigHost); InternalConfigRoot configRoot = new InternalConfigRoot(this, updateConfigHost); ((IInternalConfigRoot)configRoot).Init(implicitMachineConfigHost, isDesignTime: true); // Set the configuration paths for this Configuration. // // We do this in a separate step so that the WebConfigurationHost // can use this object's _configRoot to get the <sites> section, // which is used in it's MapPath implementation. string configPath, locationConfigPath; implicitMachineConfigHost.InitForConfiguration( ref locationSubPath, out configPath, out locationConfigPath, configRoot, hostInitConfigurationParams); if (!string.IsNullOrEmpty(locationSubPath) && !implicitMachineConfigHost.SupportsLocation) throw ExceptionUtil.UnexpectedError("Configuration::ctor"); if (string.IsNullOrEmpty(locationSubPath) != string.IsNullOrEmpty(locationConfigPath)) throw ExceptionUtil.UnexpectedError("Configuration::ctor"); // Get the configuration record for this config file. _configRecord = (MgmtConfigurationRecord)configRoot.GetConfigRecord(configPath); // Create another MgmtConfigurationRecord for the location that is a child of the above record. // Note that this does not match the resolution hierarchy that is used at runtime. if (!string.IsNullOrEmpty(locationSubPath)) { _configRecord = MgmtConfigurationRecord.Create( configRoot, _configRecord, locationConfigPath, locationSubPath); } // Throw if the config record we created contains global errors. _configRecord.ThrowIfInitErrors(); } public AppSettingsSection AppSettings => (AppSettingsSection)GetSection("appSettings"); public ConnectionStringsSection ConnectionStrings => (ConnectionStringsSection)GetSection("connectionStrings"); public string FilePath => _configRecord.ConfigurationFilePath; public bool HasFile => _configRecord.HasStream; public ConfigurationLocationCollection Locations => _locations ??= _configRecord.GetLocationCollection(this); public ContextInformation EvaluationContext => _evalContext ??= new ContextInformation(_configRecord); public ConfigurationSectionGroup RootSectionGroup { get { if (_rootSectionGroup == null) { _rootSectionGroup = new ConfigurationSectionGroup(); _rootSectionGroup.RootAttachToConfigurationRecord(_configRecord); } return _rootSectionGroup; } } public ConfigurationSectionCollection Sections => RootSectionGroup.Sections; public ConfigurationSectionGroupCollection SectionGroups => RootSectionGroup.SectionGroups; // Is the namespace declared in the file or not? // // ie. xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0" // (currently this is the only one we allow) public bool NamespaceDeclared { get { return _configRecord.NamespacePresent; } set { _configRecord.NamespacePresent = value; } } public Func<string, string> TypeStringTransformer { get { return _typeStringTransformer; } set { if (_typeStringTransformer != value) { TypeStringTransformerIsSet = value != null; _typeStringTransformer = value; } } } public Func<string, string> AssemblyStringTransformer { get { return _assemblyStringTransformer; } set { if (_assemblyStringTransformer != value) { AssemblyStringTransformerIsSet = value != null; _assemblyStringTransformer = value; } } } public FrameworkName TargetFramework { get; set; } internal bool TypeStringTransformerIsSet { get; private set; } internal bool AssemblyStringTransformerIsSet { get; private set; } internal Stack SectionsStack => _sectionsStack ??= new Stack(); // Create a new instance of Configuration for the locationSubPath, // with the initialization parameters that were used to create this configuration. internal Configuration OpenLocationConfiguration(string locationSubPath) { return new Configuration(locationSubPath, _typeConfigHost, _hostInitConfigurationParams); } // public methods public ConfigurationSection GetSection(string sectionName) { ConfigurationSection section = (ConfigurationSection)_configRecord.GetSection(sectionName); return section; } public ConfigurationSectionGroup GetSectionGroup(string sectionGroupName) { ConfigurationSectionGroup sectionGroup = _configRecord.GetSectionGroup(sectionGroupName); return sectionGroup; } public void Save() { SaveAsImpl(null, ConfigurationSaveMode.Modified, false); } public void Save(ConfigurationSaveMode saveMode) { SaveAsImpl(null, saveMode, false); } public void Save(ConfigurationSaveMode saveMode, bool forceSaveAll) { SaveAsImpl(null, saveMode, forceSaveAll); } public void SaveAs(string filename) { SaveAs(filename, ConfigurationSaveMode.Modified, false); } public void SaveAs(string filename, ConfigurationSaveMode saveMode) { SaveAs(filename, saveMode, false); } public void SaveAs(string filename, ConfigurationSaveMode saveMode, bool forceSaveAll) { if (string.IsNullOrEmpty(filename)) throw ExceptionUtil.ParameterNullOrEmpty(nameof(filename)); SaveAsImpl(filename, saveMode, forceSaveAll); } private void SaveAsImpl(string filename, ConfigurationSaveMode saveMode, bool forceSaveAll) { filename = string.IsNullOrEmpty(filename) ? null : Path.GetFullPath(filename); if (forceSaveAll) ForceGroupsRecursive(RootSectionGroup); _configRecord.SaveAs(filename, saveMode, forceSaveAll); } // Force all sections and section groups to be instantiated. private static void ForceGroupsRecursive(ConfigurationSectionGroup group) { foreach (ConfigurationSection configSection in group.Sections) { // Force the section to be read into the cache _ = group.Sections[configSection.SectionInformation.Name]; } foreach (ConfigurationSectionGroup sectionGroup in group.SectionGroups) ForceGroupsRecursive(group.SectionGroups[sectionGroup.Name]); } } }