代码之家  ›  专栏  ›  技术社区  ›  Szymon Rozga

强制ConfigurationManager重新加载所有节

  •  7
  • Szymon Rozga  · 技术社区  · 15 年前

    1. 引导程序生成配置文件。
    2. 引导程序使用新的配置文件作为配置文件初始化新的AppDomain。
    3. 因此,new AppDomain被配置为使用新的配置文件,所有这些都可以正常工作。

    我们希望摆脱这种多AppDomain方法;它增加了一层复杂性,特别是在涉及非托管库和其他遗留代码时。

    1. 引导程序将配置文件合并到自己的配置文件中。
    2. 引导程序刷新其ConfigurationManager缓存。
    3. 引导程序在同一AppDomain中启动主应用程序。

    ConfigurationManager似乎在内存中缓存了部分。例如,如果我在步骤3之前阅读AppSettings,我必须调用: ConfigurationManager.RefreshSection("appSettings"); 实际上,我必须确保引导程序使用过的任何部分都被刷新。

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

    1 回复  |  直到 15 年前
        1
  •  0
  •   Nicolas V.    11 年前

    我知道这个问题很久以前就被贴出来了,但我希望这个答案仍然有用。

    似乎没有标准的方法可以做到这一点。然而,通过访问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>();
    }
    

    “appSettings”部分也被加载了,因为我必须访问它才能使它一致地工作。

    推荐文章
    Liam  ·  C#AppSettings数组
    7 年前