Я должен сохранить 2 разные группы настроек в моей корневой группе настроек. Это должно выглядеть так:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="ROOT_GROUP">
<sectionGroup name="GROUP_1">
........................
some_settings
........................
</sectionGroup>
<sectionGroup name="GROUP_2">
........................
some_other_settings
........................
</sectionGroup>
</sectionGroup>
</configSections>
................................
other_system_tags
................................
</configuration>
Нюанс в том, что я должен сохранять его один за другим в разных местах моего кода. (Например, GROUP_1 может быть строкой соединения, а GROUP_2 - некоторыми настройками среды, и они вместе заполняются пользователями в разных разделах моего приложения)
Я сделал этот простой тестовый класс, чтобы получить ожидаемый результат
[TestFixture]
public class Tttt
{
private string ROOT_GROUP = "ROOT_GROUP";
private string GROUP_1 = "GROUP_1";
private string GROUP_2 = "GROUP_2";
[Test]
public void SaveSettingsGroups()
{
SaveGroup1();
SaveGroup2();
Assert.True(true);
}
private Configuration GetConfig()
{
var configFilePath = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
var map = new ExeConfigurationFileMap { ExeConfigFilename = configFilePath };
var config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
return config;
}
private void SaveGroup1()
{
var config = GetConfig();
var root = new UserSettingsGroup();
config.SectionGroups.Add(ROOT_GROUP, root);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(root.Name);
var nested = new UserSettingsGroup();
root.SectionGroups.Add(GROUP_1, nested);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(nested.Name);
}
private void SaveGroup2()
{
var config = GetConfig();
var root = config.GetSectionGroup(ROOT_GROUP);
var nested = new UserSettingsGroup();
root.SectionGroups.Add(GROUP_2, nested);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(nested.Name);
}
}
НО по какой-то причине результат этого кода другой
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="ROOT_GROUP">
<sectionGroup name="GROUP_1">
........................
some_settings
........................
</sectionGroup>
</sectionGroup>
<sectionGroup name="ROOT_GROUP">
<sectionGroup name="GROUP_2">
........................
some_other_settings
........................
</sectionGroup>
</sectionGroup>
</configSections>
................................
other_system_tags
................................
</configuration>
Узел ROOT_GROUP дублирован, и, конечно, Visual Studio выдает мне исключение, что ROOT_GROUP уже существует. Очевидно, моя проблема скрыта в методе SaveGroup2 (), когда я добавляю новую вложенную группу в существующую корневую группу, а затем сохраняю ее - но почему?
UPD
Я только что добавил новый метод
private void SaveGroup3()
{
var config = GetConfig();
var root = config.GetSectionGroup(ROOT_GROUP);
var nested1 = root.SectionGroups.Get(0);
var nested2 = new UserSettingsGroup();
var nested3 = new UserSettingsGroup();
nested1.SectionGroups.Add("GROUP_2", nested2);
root.SectionGroups.Add("GROUP_3", nested3);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(nested2.Name);
ConfigurationManager.RefreshSection(nested3.Name);
}
И заменить его в тесте
[Test]
public void SaveSettingsGroups()
{
SaveGroup1();
SaveGroup3();
Assert.True(true);
}
И получил это странное поведение
<sectionGroup name="ROOT_GROUP">
<sectionGroup name="GROUP_1">
<sectionGroup name="GROUP_2">
</sectionGroup>
</sectionGroup>
<sectionGroup name="GROUP_3">
</sectionGroup>
</sectionGroup>
Как видите, странность в том, что результат полностью ожидаемый. ROOT_GROUP не был дубликатом, так как мне это было нужно, но почему это происходит в SaveGroup2 ()? Я что-то пропустил в SaveGroup2 ()?
UPD2 - HACK
Только что попробовал простую идею - что если я очистил бы группу root_group перед добавлением в нее нового вложенного элемента?
private void SaveGroup2()
{
var config = GetConfig();
var root = config.GetSectionGroup(ROOT_GROUP);
var nested = new ConfigurationSectionGroup();
//Copy exiting nested groups to array
var gr = new ConfigurationSectionGroup[5];
root.SectionGroups.CopyTo(gr,0);
gr[1] = nested;
//<!----
root.SectionGroups.Clear();
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(root.Name);
root.SectionGroups.Add(gr[0].Name, gr[0]);
root.SectionGroups.Add(GROUP_2, gr[1]);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(root.Name);
}
А как вы, наверное, догадались - это работает!
<sectionGroup name="ROOT_GROUP">
<sectionGroup name="GROUP_1" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
</sectionGroup>
<sectionGroup name="GROUP_2" type="System.Configuration.ConfigurationSectionGroup, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" >
</sectionGroup>
</sectionGroup>
Я думаю, что это похоже на ошибку или есть некоторые скрытые вещи, которые я пропустил. Может кто-нибудь объяснить мне, что я сделал не так?