强制 ConfigurationManager 重新加载所有部分

7
我正在编写一个配置系统,其中app.config文件是从分布在多个位置的各种配置片段动态构建的。该系统目前的工作流程如下:
  1. 引导程序构建配置文件。
  2. 引导程序使用新配置文件初始化新的AppDomain作为配置文件。
  3. 结果,新的AppDomain被配置为使用新的配置文件,一切正常。
我们希望摆脱这种多AppDomain方法;它增加了一层复杂性,尤其是涉及非托管库和其他传统代码时。
移动到一个AppDomain后,工作流程将更改为:
  1. 引导程序构建配置文件。
  2. 引导程序将配置文件合并到自己的配置文件中。
  3. 引导程序刷新其ConfigurationManager缓存。
  4. 引导程序在同一个AppDomain中启动主应用程序。
看起来ConfigurationManager会在内存中缓存节。例如,如果我在第3步之前读取AppSettings,则必须调用:ConfigurationManager.RefreshSection("appSettings");实际上,我必须确保引导程序使用的任何部分都已被刷新。
我能够迭代新配置文件中的所有配置部分并强制刷新它们,但这会强制配置管理器加载在配置文件中引用的任何程序集。如果可能,我想推迟这个过程。是否有一种方法来使ConfigurationManager内存中当前的部分无效?
1个回答

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类的实现,则随时可能出现问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接