克隆一个没有自定义类的通用ConfigurationSection
本文关键字:自定义 ConfigurationSection 一个 | 更新日期: 2023-09-27 18:06:09
我正在尝试从外部app.config文件的配置中复制ConfigurationSection
,最终目标是将其合并到执行应用程序当前加载的配置中。
的目的是允许许多库,加载到单独的appdomain,从执行应用程序接收配置和有自己的app.config设置合并,以便读取任何设置是一个简单的调用ConfigurationManager.AppSettings
或ConfigurationManager.GetSection()
。
我遇到的问题是克隆一个ConfigurationSection
。
我试过了:
-
ConfigurationSectionCloner
in Enterprise Library.Configuration externalConfig = ConfigurationManager.OpenExeConfiguration(externalLibPath); var section = externalConfig.GetSection("some.section"); ConfigurationSectionCloner sectionCloner = new ConfigurationSectionCloner(); section = sectionCloner.Clone(section); Configuration localConfig = ConfigurationManager.OpenExecConfiguration(ConfigurationUserLevel.None); localConfig.Sections.Add("some.section", section);
- 这个运行正常,但是,
localConfig.GetSection("some.section")
和ConfigurationManager.GetSection("some.section")
都是空的。 - 即使调用
localConfig.Save()
(使用任何参数组合)也不会填充该section。
- 这个运行正常,但是,
-
CompositeConfigurationSourceHandler
in Enterprise LibrarySystemConfigurationSource localConfig = new SystemConfigurationSource(); FileConfigurationSource externalConfig = new FileConfigurationSource(externalLibPath + ".config"); CompositeConfigurationSourceHandler ccsh = new CompositeConfigurationSourceHandler(externalConfig); ConfigurationSection section = externalConfig.GetSection("some.section"); if (!ccsh.CheckAddSection("some.section", section)) { try { localConfig.Add("some.section", section); } catch (Exception) { } }
- 这会在
localConfig.add()
行抛出一个异常,说明Cannot add a ConfigurationSection that already belongs to the Configuration.
。问题是localConfig
没有有该部分。即使添加localConfig.Remove("some.section");
也无法解决。 - 我也尝试了一些
*ConfigurationSource
对象的组合,看看它们是否有所不同,但没有。
- 这会在
从appSettings
块复制实际的ApplicationSettings,甚至从connectionStrings
块复制ConnectionStrings是超级简单的调用,如ConfigurationManager.AppSettings.Set("some key", "some value");
,但它似乎不那么容易与ConfigurationSections。
是否有一种方法来复制,克隆和/或只是简单地合并一个ConfigurationSection
从一个配置到另一个?
指出:
- 我不想合并物理文件。一切都应该在运行时发生,并且只保留在内存中。我不想写一个自定义类来表示每个ConfigurationSection。这些节将是通用的,对于执行的应用程序来说是未知的。
我已经找到了一种方法来合并从任何app.config文件中读取的ConfigurationSection
与主执行应用程序加载的配置!
该方法使用企业库中的ConfigurationSectionCloner
扩展了#1的代码:
// 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);
奇怪的是,在我所有的测试中,上面的步骤都是所有必需的。每个节需要的主要操作是设置新节的Type
、调用SetRawXml()
和刷新该节。
这种方法的缺点是,与我最初的愿望相反,对localConfig.Save()
的调用将它保存到磁盘上,覆盖了原始的app.config文件。在多个appdomain中异步执行此操作会导致争用问题,但这是另一个主题!