I have figured out a method to merge a ConfigurationSection
that has been read from any app.config file with the main executing application's loaded config!
The method extends my code for #1 using the ConfigurationSectionCloner
from the Enterprise Library:
// open the external configuration
Configuration externalConfig = ConfigurationManager.OpenExeConfiguration(externalLibPath);
// get the section we're looking to clone & merge
var sectionToClone = externalConfig.GetSection(sectionName);
// "clone" the section; this will create a `DefaultSection` object - not a "pure clone" =[
ConfigurationSectionCloner sectionCloner = new ConfigurationSectionCloner();
var clonedSection = sectionCloner.Clone(sectionToClone);
// set the `Type` of the new section to the one we're cloning (most likely a NameValueCollection)
clonedSection.SectionInformation.Type = sectionToClone.SectionInformation.Type;
// set the new section's XML to match the original one (really? the cloner doesn't do this?!)
clonedSection.SectionInformation.SetRawXml(sectionToClone.SectionInformation.GetRawXml());
// open our local configuration (the "executing application's config)
Configuration localConfig = ConfigurationManager.OpenExecConfiguration(ConfigurationUserLevel.None);
// add the cloned section to it
localConfig.Sections.Add(sectionName, clonedSection);
// save the section (this can be any variation-of-parameters for `.Save()`)
localConfig.Save(ConfigurationSaveMode.Minimal);
// force ConfigurationManager to refresh the new section
ConfigurationManager.RefreshSection(sectionName);
Oddly, in all of my tests, the above steps are all required. The primary ones needed, per-section, are to set the new section's Type
, to call SetRawXml()
, and to refresh the section.
The downside to this approach, against what my original desires were, is that the call to localConfig.Save()
saves it to disk overwriting the original app.config file. Doing this asynchronously in multiple AppDomains causes contention-issues, but that's a different topic!