Как получить все разделы по имени в разделеСообщество в группеНастройки в .Net 2.0

Вот идея, которую я имел:

Я хочу, чтобы маленький исполняемый файл имел файл app.config с несколькими разделами, которые находятся в разделе "Настройки приложения" (не "appSettings", мне не нужно писать в файл). Каждый раздел будет иметь имя, соответствующее модулю, который должен быть загружен, если он установлен.

Вот пример:

   <configuration>
     <configSections>
       <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
         <section name="Executable" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
         <section name="FirstModule" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
       </sectionGroup>
     </configSections>
     <applicationSettings>
       <Executable>
         <setting name="MyFirstSetting" serializeAs="String">
           <value>My awesome feature setting</value>
         </setting>
       </Executable>
       <FirstModule path="path to the modules assembly">
         <setting name="ImportantSettingToTheModule" serializeAs="String">
           <value>Some important string</value>
         </setting>
       </FirstModule>
     </applicationSettings>
   </configuration>

Теперь, если я определяю раздел FirstModule, я хочу, чтобы мое приложение загрузило его сборку. Если раздел не определен, модуль не должен загружаться. Это должно быть верно для не только одного модуля, но еще не определенного числа из них.

Поэтому мне в основном нужно узнать о определенных разделах во время выполнения. Как мне это сделать?

Кроме того, я хочу, чтобы это стало переносимым исполняемым файлом (= он должен работать и на Mono), который обратно совместим с .NET 2.0.

Возможно, было бы интересно посмотреть проект на GitHub (в настоящее время на этот коммит).

Ответ 1

Посмотрите на функцию ConfigurationManager.OpenExeConfiguration для загрузки в файл конфигурации.

Затем в классе System.Configuration.Configuration, который вы вернетесь из ConfigurationManager.OpenExeConfiguration, вы захотите посмотреть SectionGroups имущество. Это вернет ConfigurationSectionGroupCollection, в котором вы найдете раздел applicationSettings.

В ConfigurationSectionGroupCollection будет существовать свойство Sections, которое содержит объекты Executable и FirstModule ConfigurationSection.

var config = ConfigurationManager.OpenExeConfiguration(pathToExecutable);
var applicationSettingSectionGroup = config.SectionGroups["applicationSettings"];
var executableSection = applicationSettingSectionGroup.Sections["Executable"];
var firstModuleSection = applicationSettingSectionGroup.Sections["FirstModule"];

После получения объектов ConfigurationSectionGroupCollection или ConfigurationSection вы захотите проверить null. Если они ноль, они не существуют в файле configuraiton.

Вы также можете получить разделы, используя ConfigurationManager.GetSection

var executableSection = (ClientSettingsSection)ConfigurationManager
    .GetSection("applicationSettings/Executable");
var firstModuleSection = (ClientSettingsSection)ConfigurationManager
    .GetSection("applicationSettings/FirstModule");

Опять же, если объекты null, они не существуют в файле конфигурации.

Чтобы получить список всех названий и групп разделов, которые вы могли бы сделать:

var config = ConfigurationManager.OpenExeConfiguration(pathToExecutable);
var names = new List<string>();
foreach (ConfigurationSectionGroup csg in config.SectionGroups)
    names.AddRange(GetNames(csg));

foreach (ConfigurationSection cs in config.Sections)
    names.Add(cs.SectionInformation.SectionName);

private static List<string> GetNames(ConfigurationSectionGroup configSectionGroup)
{
    var names = new List<string>();

    foreach (ConfigurationSectionGroup csg in configSectionGroup.SectionGroups)
        names.AddRange(GetNames(csg));

    foreach(ConfigurationSection cs in configSectionGroup.Sections)
        names.Add(configSectionGroup.SectionGroupName + "/" + cs.SectionInformation.SectionName);

    return names;
}