7

Sto scrivendo un sistema di configurazione in cui il file app.config è costruito dinamicamente da vari frammenti di configurazione distribuiti in più posizioni. Il sistema funziona attualmente come segue:Forzare ConfigurationManager per ricaricare tutte le sezioni

  1. Bootstrapper crea il file di configurazione.
  2. Bootstrapper inizializza il nuovo AppDomain con il nuovo file di configurazione come file di configurazione.
  3. Di conseguenza, il nuovo AppDomain è configurato per utilizzare il nuovo file di configurazione e tutto funziona correttamente.

Ci piacerebbe allontanarci da questo approccio a più AppDomain; aggiunge un livello di complessità, specialmente quando si tratta di librerie non gestite e altri codici legacy.

a trasferirsi in un AppDomain, il flusso di lavoro cambierebbe a:

  1. Bootstrapper costruisce file di configurazione.
  2. Bootstrapper unisce il file di configurazione nel proprio file di configurazione.
  3. Bootstrapper aggiorna la propria cache di ConfigurationManager.
  4. Bootstrapper avvia l'app principale nello stesso AppDomain.

Sembra che il ConfigurationManager memorizzi nella cache le sezioni. Ad esempio, se leggo AppSettings prima del punto 3, devo chiamare: ConfigurationManager.RefreshSection("appSettings"); Infatti, devo assicurarmi che ogni sezione che è stata usata dal bootstrapper sia aggiornata.

Sono in grado di eseguire l'iterazione su tutte le sezioni di configurazione nel nuovo file di configurazione e forzare l'aggiornamento, ma ciò impone al gestore di configurazione di caricare qualsiasi assembly a cui fa riferimento nel file di configurazione. Mi piacerebbe differire questo se possibile. Se esiste un modo per invalidare ciò che il ConfigurationManager ha attualmente in memoria?

risposta

0

So che la domanda è stata postata molto tempo fa ma spero che questa risposta sarà comunque utile.

Sembra che non ci sia un modo standard per farlo. Tuttavia, accedendo ai campi interni e ai tipi della classe ConfigurationManager, sono riuscito a elencare tutte le sezioni caricate. Ecco come l'ho fatto:

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

La sezione "system.diagnostics" sembra essere sempre caricata. Anche la sezione "appSettings" viene caricata poiché devo accedervi per farlo funzionare in modo coerente.

Questo funziona sulla mia macchina (.NET 4.5) ma poiché si basa su elementi interni, può interrompersi in qualsiasi momento se Microsoft decide di modificare l'implementazione della classe ConfigurationManager.