2013-03-26 49 views
0

我试图从外部app.config文件与合并成执行应用程序的当前加载配置的最终目标配置做出ConfigurationSection的副本。克隆一个通用的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()行指出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从一个配置合并到另一个配置?

注:

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

回答

2

我已经想出了一种方法,将从任何app.config文件中读取的ConfigurationSection与主执行应用程序的加载配置合并!

的方法,使用所述ConfigurationSectionClonerEnterprise Library延伸我的代码为#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中异步执行此操作会导致争用问题,但这是另一个话题!

+0

在重新审视之后,上述所有(EnterpriseLibrary)都相当过度膨胀,可以用简单的XML合并工具完成(然后使用'SetRawXml()'方法) – newfurniturey 2013-12-16 21:27:09

+0

我使用Entlib 6和那里不需要明确地检索和设置sectionInformation,只需调用Clone()。 – Legends 2015-05-03 16:43:57