7 Stimmen

ConfigurationManager zum Neuladen aller Abschnitte zwingen

Ich schreibe ein Konfigurationssystem, in dem die app.config-Datei dynamisch aus verschiedenen Konfigurationsfragmenten erstellt wird, die über mehrere Standorte verteilt sind. Das System funktioniert derzeit wie folgt:

  1. Der Bootstrapper erstellt die Konfigurationsdatei.
  2. Der Bootstrapper initialisiert eine neue AppDomain mit der neuen Konfigurationsdatei als Konfigurationsdatei.
  3. Als Ergebnis ist die neue AppDomain so konfiguriert, dass sie die neue Konfigurationsdatei verwendet und alles funktioniert einwandfrei.

Wir würden gerne von diesem Ansatz mit mehreren AppDomains wegkommen, da er die Komplexität erhöht, insbesondere wenn es um nicht verwaltete Bibliotheken und anderen Legacy-Code geht.

Beim Wechsel zu einer AppDomain würde sich der Arbeitsablauf ändern:

  1. Der Bootstrapper erstellt die Konfigurationsdatei.
  2. Der Bootstrapper fügt die Konfigurationsdatei in seine eigene Konfigurationsdatei ein.
  3. Der Bootstrapper aktualisiert seinen ConfigurationManager-Cache.
  4. Der Bootstrapper startet die Hauptanwendung in derselben AppDomain.

Es scheint, dass der ConfigurationManager Abschnitte im Speicher zwischenspeichert. Wenn ich also zum Beispiel die AppSettings vor Schritt #3 lese, muss ich aufrufen: ConfigurationManager.RefreshSection("appSettings"); In der Tat muss ich sicherstellen, dass jeder Abschnitt, der vom Bootstrapper verwendet wurde, aktualisiert wird.

Ich bin in der Lage, über alle Konfigurationsabschnitte in der neuen Konfigurationsdatei zu iterieren und erzwingen Sie aktualisieren, aber dies zwingt den Konfigurations-Manager, um alle Baugruppen in der Konfigurationsdatei referenziert zu laden. Ich würde dies gerne aufschieben, wenn möglich. Gibt es eine Möglichkeit, das, was der ConfigurationManager derzeit im Speicher hat, ungültig zu machen?

0voto

Nicolas V. Punkte 1

Ich weiß, dass die Frage schon vor langer Zeit gestellt wurde, aber ich hoffe, dass diese Antwort immer noch nützlich ist.

Anscheinend gibt es keine Standardmethode für diese Aufgabe. Durch den Zugriff auf interne Felder und Typen der Klasse ConfigurationManager konnte ich jedoch alle geladenen Abschnitte auflisten. So habe ich es gemacht:

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

Der Abschnitt "system.diagnostics" scheint immer geladen zu sein. Der Abschnitt "appSettings" wird ebenfalls geladen, da ich auf ihn zugreifen muss, damit er konsistent funktioniert.

Dies funktioniert auf meinem Rechner (.NET 4.5), aber da es sich auf internes Material stützt, kann es jederzeit abbrechen, wenn Microsoft beschließt, die Implementierung der ConfigurationManager-Klasse zu ändern.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X