c# - 克隆通用 ConfigurationSection 而不使用自定义类

标签 c# .net app-config configurationmanager

我正在尝试从外部 app.config 文件的配置中复制 ConfigurationSection ,最终目标是将其合并到执行应用程序当前加载的配置中。

目的是允许加载到各个 AppDomain 中的众多库从执行应用程序接收配置合并它们自己的 app.config 设置,以便读取任何设置都是一个简单的调用ConfigurationManager.AppSettingsConfigurationManager.GetSection()

我遇到的问题是克隆 ConfigurationSection

我尝试过的:

  1. ConfigurationSectionCloner在企业库中。

    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()(使用任意参数组合)也不会填充该部分。

  2. CompositeConfigurationSourceHandler在企业库中

    SystemConfigurationSource 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() 行引发异常,指出无法添加已属于 Configuration 的 ConfigurationSection。。问题是 localConfig 没有该部分。即使添加 localConfig.Remove("some.section"); 也无法解决。
    • 我还尝试了多种 *ConfigurationSource 对象的组合,看看它们是否有所不同,但没有任何效果。

通过诸如 ConfigurationManager.AppSettings.Set( "some key", "some value"); 但使用 ConfigurationSections 似乎并不那么容易。

有没有办法将 ConfigurationSection 从一个配置复制、克隆和/或简单地合并到另一个配置中?

注释:

  1. 我不想合并物理文件。一切都应该在运行时发生并仅保留在内存中。
  2. 我不想编写一个自定义类来表示每个 ConfigurationSection。这些部分是通用的,并且对于执行应用程序来说是未知的。

最佳答案

我找到了一种合并 ConfigurationSection 的方法已从任何具有主执行应用程序加载配置的 app.config 文件中读取!

该方法使用 ConfigurationSectionCloner 扩展我的代码 #1来自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);

奇怪的是,在我的所有测试中,上述步骤都是全部必需的。每个部分所需的主要内容是设置新部分的 Type ,调用SetRawXml() ,然后刷新该部分。

与我最初的愿望相反,这种方法的缺点是,对 localConfig.Save() 的调用会将其保存到磁盘,覆盖原始的 app.config 文件。在多个 AppDomain 中异步执行此操作会导致争用问题,但这是另一个主题!

关于c# - 克隆通用 ConfigurationSection 而不使用自定义类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15640330/

相关文章:

c# - 我可以使用哪些项目模板来创建 winform dll 库?

c# - 如何通过代码获取日志文件名?

c# - 如何在 WinCE Compact Framework 3.5 中标记用户控件的默认事件

c# - 使用 UnityContainer 进行动态 IOC 映射 - 如何实现?

c# - 从 DLL 调用函数?

c# - ConfigurationSettings.AppSettings 已过时,警告

c# - 使用配置转换使用 MSI 部署的桌面应用程序在 VSTS 上构建/发布流程

c# - 在 C# 中执行基于存储过程的查询后,如何为 CommandText 重新使用 SqlCommand 对象?

c# - 依赖属性绑定(bind)未更新

c# - 具有多个具有相同值的项目时的 AutoCompleteBox 问题