强制ConfigurationManager重新加载所有部分

时间:2009-07-06 15:12:29

标签: .net configuration configurationmanager configurationsection

我正在编写一个配置系统,其中app.config文件是从分布在多个位置的各种配置片段动态构建的。该系统目前的工作原理如下:

  1. Bootstrapper构建配置文件。
  2. Bootstrapper使用新的配置文件作为配置文件初始化新的AppDomain。
  3. 因此,新的AppDomain配置为使用新的配置文件,一切正常。
  4. 我们希望摆脱这种多AppDomain方法;它增加了一层复杂性,特别是涉及非托管库和其他遗留代码时。

    在迁移到一个AppDomain时,工作流程将更改为:

    1. Bootstrapper构建配置文件。
    2. Bootstrapper将配置文件合并到自己的配置文件中。
    3. Bootstrapper刷新其ConfigurationManager缓存。
    4. Bootstrapper在同一个AppDomain中启动主应用程序。
    5. 似乎ConfigurationManager在内存中缓存部分。因此,例如,如果我在步骤#3之前阅读AppSettings,我必须调用:ConfigurationManager.RefreshSection("appSettings");实际上,我必须确保刷新了引导程序使用的任何部分。

      我能够遍历新配置文件中的所有配置部分并强制刷新它们,但是,这会强制配置管理器加载配置文件中引用的任何程序集。如果可能的话,我想推迟这个。如果有办法使ConfigurationManager当前在内存中的内容无效?

1 个答案:

答案 0 :(得分:0)

我知道这个问题是很久以前发布的,但我希望这个答案仍然有用。

似乎没有标准的方法来做到这一点。但是,通过访问ConfigurationManager类的内部字段和类型,我能够列出所有已加载的部分。我就这样做了:

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>();
}

似乎总是加载“system.diagnostics”部分。 “appSettings”部分也被加载,因为我必须访问它以使其一致地工作。

这适用于我的机器(.NET 4.5),但由于它依赖于内部资源,如果Microsoft决定更改ConfigurationManager类的实现,它可能随时中断。