7

Я пишу конфигурационную систему, в которой файл app.config динамически создается из различных фрагментов конфигурации, распределенных в разных местах. Система в настоящее время работает следующим образом:Задание ConfigurationManager для перезагрузки всех разделов

  1. Bootstrapper создает файл конфигурации.
  2. Bootstrapper инициализирует новый AppDomain с новым конфигурационным файлом в качестве файла конфигурации.
  3. В результате новый AppDomain настроен на использование нового файла конфигурации, и все работает нормально.

Мы хотели бы отойти от этого многократного подхода AppDomain; он добавляет уровень сложности, особенно когда речь заходит о неуправляемых библиотеках и другом устаревшем коде.

При переходе к одной AppDomain рабочий процесс изменится на:

  1. Загрузчик строит конфигурационный файл.
  2. Bootstrapper объединяет конфигурационный файл в собственный файл конфигурации.
  3. Bootstrapper обновляет его кеш ConfigurationManager.
  4. Bootstrapper запускает основное приложение в том же AppDomain.

Кажется, что ConfigurationManager кэширует разделы в памяти. Например, если я прочитал AppSettings до шага № 3, мне нужно позвонить: 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.

 Смежные вопросы

  • Нет связанных вопросов^_^