7

我寫在其中app.config文件被動態地從分佈在多個位置配置各個片段以構建一個配置系統。該系統目前的工作原理如下:強制ConfigurationManager中重新加載所有部分

  1. 引導程序生成配置文件。
  2. 引導程序以新的配置文件作爲配置文件初始化新的AppDomain。
  3. 因此,新的AppDomain被配置爲使用新的配置文件,並且一切正常。

我們想從這個多重的AppDomain辦法移開;它增加了一層複雜性,特別是涉及非託管庫和其他遺留代碼時。

  1. 引導程序建立配置文件:

    在移動到一個應用程序域,工作流會發生變化。

  2. Bootstrapper將配置文件合併到它自己的配置文件中。
  3. 引導程序刷新其ConfigurationManager高速緩存。
  4. 引導程序在同一AppDomain中啓動主應用程序。

看來,ConfigurationManager中緩存在內存中的部分。例如,如果我在步驟#3之前閱讀AppSettings,則必須調用:ConfigurationManager.RefreshSection("appSettings");實際上,我必須確保引導程序使用的任何部分都已刷新。

我可以遍歷所有的配置部分,在新的配置文件,並強行刷新他們,但是,這迫使配置管理器來加載在配置文件中引用的任何程序集。如果可能的話,我想延期。如果有辦法使ConfigurationManager當前在內存中的內容失效嗎?

回答

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類的實現,它可以在任何時候中斷。