Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ConfigurationManager to load config from an arbitrary location

People also ask

What is ConfigurationManager configuration?

The ConfigurationManager class enables you to access machine, application, and user configuration information. This class replaces the ConfigurationSettings class, which is deprecated. For web applications, use the WebConfigurationManager class.

What is the use of ConfigurationManager AppSettings?

Retrieves a specified configuration section for the current application's default configuration.

Does ConfigurationManager work in .NET core?

ConfigurationManager was added to support ASP.NET Core's new WebApplication model, used for simplifying the ASP.NET Core startup code.

What is ConfigurationManager C#?

ConfigurationManager is the class which helps to read data from configurations. Provides access to configuration files for client applications. Namespace: System.Configuration. To use the ConfigurationManager class, your project must reference the System.


Try this:

System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);

Another solution is to override the default environment configuration file path.

I find it the best solution for the of non-trivial-path configuration file load, specifically the best way to attach configuration file to dll.

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", <Full_Path_To_The_Configuration_File>);

Example:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", @"C:\Shared\app.config");

More details may be found at this blog.

Additionally, this other answer has an excellent solution, complete with code to refresh the app config and an IDisposable object to reset it back to it's original state. With this solution, you can keep the temporary app config scoped:

using(AppConfig.Change(tempFileName))
{
    // tempFileName is used for the app config during this context
}

Ishmaeel's answer generally does work, however I found one issue, which is that using OpenMappedMachineConfiguration seems to lose your inherited section groups from machine.config. This means that you can access your own custom sections (which is all the OP wanted), but not the normal system sections. For example, this code will not work:

ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath);
Configuration configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
MailSettingsSectionGroup thisMail = configuration.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup;  // returns null

Basically, if you put a watch on the configuration.SectionGroups, you'll see that system.net is not registered as a SectionGroup, so it's pretty much inaccessible via the normal channels.

There are two ways I found to work around this. The first, which I don't like, is to re-implement the system section groups by copying them from machine.config into your own web.config e.g.

<sectionGroup name="system.net" type="System.Net.Configuration.NetSectionGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <sectionGroup name="mailSettings" type="System.Net.Configuration.MailSettingsSectionGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <section name="smtp" type="System.Net.Configuration.SmtpSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </sectionGroup>
</sectionGroup>

I'm not sure the web application itself will run correctly after that, but you can access the sectionGroups correctly.

The second solution it is instead to open your web.config as an EXE configuration, which is probably closer to its intended function anyway:

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = strConfigPath };
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
MailSettingsSectionGroup thisMail = configuration.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup;  // returns valid object!

I daresay none of the answers provided here, neither mine or Ishmaeel's, are quite using these functions how the .NET designers intended. But, this seems to work for me.


The accepted answer is wrong!!

It throws the following exception on accessing the AppSettings property:

Unable to cast object of type 'System.Configuration.DefaultSection' to type 'System.Configuration.AppSettingsSection'.

Here is the correct solution:

System.Configuration.ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "YourFilePath";
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);