Forcing ConfigurationManager to reboot all partitions

I am writing a configuration system in which the app.config file is dynamically created from various pieces of configuration distributed over several locations. Currently, the system works as follows:

  • Bootstrapper creates a configuration file.
  • Bootstrapper initializes the new AppDomain with the new configuration file as the configuration file.
  • As a result, the new AppDomain is configured to use the new configuration file, and everything works fine.

We would like to move away from this multiple AppDomain approach; it adds a level of complexity, especially when it comes to unmanaged libraries and other legacy code.

Upon transition to one AppDomain the workflow will change to:

  • Bootstrapper creates a configuration file.
  • Bootstrapper combines the configuration file into its own configuration file.
  • Bootstrapper updates its ConfigurationManager cache.
  • Bootstrapper launches the main application in the same AppDomain.

It seems that ConfigurationManager is caching partitions in memory. So, for example, if I read AppSettings before step 3, I have to call: ConfigurationManager.RefreshSection("appSettings"); In fact, I have to make sure that any section used by the bootloader is updated.

I can iterate through all the configuration sections in the new configuration file and force them to update, but this forces the configuration manager to load any assemblies specified in the configuration file. I would like to postpone this if possible. If there is a way to invalidate what the ConfigurationManager currently has in memory?

+7
configuration configurationmanager configurationsection
source share
1 answer

I know the question was posted a long time ago, but I hope this answer is still useful.

There seems to be no standard way to do this. However, gaining access to the internal fields and types of the ConfigurationManager class, I was able to list all the loaded sections. Here is how I did it:

 private static IEnumerable<string> GetLoadedSections() { // s_configSystem can be null if the ConfigurationManager is not properly loaded. Accessing the AppSettings *should* do the trick. var appSettings = ConfigurationManager.AppSettings; FieldInfo s_configSystemField = typeof(ConfigurationManager).GetField("s_configSystem", BindingFlags.NonPublic | BindingFlags.Static); object s_configSystem = s_configSystemField.GetValue(null); FieldInfo _completeConfigRecordField = s_configSystem.GetType().GetField("_completeConfigRecord", BindingFlags.NonPublic | BindingFlags.Instance); object _completeConfigRecord = _completeConfigRecordField.GetValue(s_configSystem); FieldInfo _sectionRecordsField = _completeConfigRecord.GetType().GetField("_sectionRecords", BindingFlags.NonPublic | BindingFlags.Instance); Hashtable _sectionRecords = (Hashtable)_sectionRecordsField.GetValue(_completeConfigRecord); return _sectionRecords.Keys.OfType<string>(); } 

The "system.diagnostics" section is always loading. The appSettings section is also loading, as I have to access it in order for it to work sequentially.

This works on my machine (.NET 4.5), but since it relies on internal things, it can be broken at any time if Microsoft decides to change the implementation of the ConfigurationManager class.

0
source share

All Articles