Я нашел отличный пример для обработчика пользовательской конфигурации и попытался использовать его. для моей собственной реализации.
Я настроил App.config следующим образом:
<configSections>
<section name="DocumentationSettings" type="ConfigHandler.DocumentationSettings,Settings"/>
</configSections>
<DocumentationSettings>
<DocumentationSections>
<DocumentationSection Id="AAA">
<SectionDescription Value="SectionDescriptionAAA"/>
</DocumentationSection>
<DocumentationSection Id="BBB">
<SectionDescription Value="SectionDescriptionBBB"/>
</DocumentationSection>
<DocumentationSection Id="CCC">
<SectionDescription Value="SectionDescriptionCCC"/>
</DocumentationSection>
</DocumentationSections>
</DocumentationSettings>
Я использую этот код для доступа к моей пользовательской конфигурации:
DocumentationSettings documentationSettings = ConfigurationManager.GetSection("DocumentationSettings") as DocumentationSettings;
foreach (DocumentationSectionConfigElement section in (documentationSettings.DocumentationSections.Sections))
{
Console.WriteLine(section.Id);
Console.WriteLine(section.SectionDescription.Properties.Value);
}
Первая «Console.WriteLine» работает отлично.
Итак, у меня есть следующие проблемы и вопросы, связанные с реализацией:
Я получаю ошибку на втором «Console.WriteLine», ошибка: нераспознанный атрибут «Значение». Я поместил «public SectionDescription SectionDescription», поскольку класс «DocumentationSectionConfigElement» предоставляет доступ к свойствам, но я могу ошибаться, я сначала попытался поместить его в «DocumentationSectionCollection», но я не знаю, как его там реализовать, и мне кажется, что «DocumentationSectionCollection» реализует только логику «Коллекции».
Я хочу получить доступ к «полям» либо так:
section.Id section.SectionDescription.Value
или вот так:
section.Properties.Id
section.SectionDescription.Properties.Value
Я вижу, что «Коллекция» позволяет использовать эти свойства напрямую, используя такие методы индексатора:
public DocumentationSectionConfigElement this[int index]
Но я не могу реализовать метод индексатора в классе «SectionDescription», потому что это отдельный раздел, а не коллекция, поэтому это имя «Свойства» сохраняется, когда я обращаюсь к полям.
Что мне нужно добавить, чтобы иметь возможность использовать LINQ для этих объектов конфигурации? Я имею в виду вот так:
(DocumentationSettings.DocumentationSections.Sections) .Select (x => x.Id)
Есть ли действительно хорошие примеры обработчика конфигурации сложной структуры XML? Из тех, что я обнаружил, в основном были такие простые структуры:
но нет никакого примера такой сложной структуры:
<section>
<subSections>
<subSection name="111">
<Description Value="AAA"></Description>
<Headers>
<Header type="Main">
<Properties>
<Property name="Property1"/>
<Property name="Property2"/>
<Property name="Property3"/>
</Properties>
</Header>
</Headers>
</subSection>
</subSections>
</section>
что ближе к реальным сценариям, когда нужно лучше организовать конфигурацию приложения.
В чем смысл тега sectionGroup в configSections, если «Custom Configuration Handler» работает и достаточно одного зарегистрированного «раздела»?
Почему все это так сложно? Я потратил так много времени на эти «нестандартные конфигурации», которые, как мне кажется, не должны быть такими сложными. Нет ли надстроек Visual Studio, которые обрабатывают эти вещи и генерируют код на основе структуры конфигурации XML?
Вот моя реализация обработчика конфигурации:
public class DocumentationSettings : ConfigurationSection
{
[ConfigurationProperty("DocumentationSections")]
public DocumentationSections DocumentationSections
{
get { return (DocumentationSections)base["DocumentationSections"]; }
}
}
public class DocumentationSections : ConfigurationElement
{
[ConfigurationProperty("", IsDefaultCollection = true)]
public DocumentationSectionCollection Sections
{
get { return (DocumentationSectionCollection)base[""]; }
}
}
public class SectionDescription : ConfigurationElement
{
[ConfigurationProperty("SectionDescription")]
public new SectionDescriptionConfigElement Properties
{
get { return (SectionDescriptionConfigElement)base["SectionDescription"]; }
}
}
public class DocumentationSectionCollection : ConfigurationElementCollection
{
public DocumentationSectionCollection()
{
DocumentationSectionConfigElement details = (DocumentationSectionConfigElement)CreateNewElement();
if (details.Id != "")
{
Add(details);
}
}
public override ConfigurationElementCollectionType CollectionType
{
get { return ConfigurationElementCollectionType.BasicMap; }
}
protected override ConfigurationElement CreateNewElement()
{
return new DocumentationSectionConfigElement();
}
protected override Object GetElementKey(ConfigurationElement element)
{
return ((DocumentationSectionConfigElement)element).Id;
}
public DocumentationSectionConfigElement this[int index]
{
get { return (DocumentationSectionConfigElement)BaseGet(index); }
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
new public DocumentationSectionConfigElement this[string name]
{
get { return (DocumentationSectionConfigElement)BaseGet(name); }
}
public int IndexOf(DocumentationSectionConfigElement details)
{
return BaseIndexOf(details);
}
public void Add(DocumentationSectionConfigElement details)
{
BaseAdd(details);
}
protected override void BaseAdd(ConfigurationElement element)
{
BaseAdd(element, false);
}
public void Remove(DocumentationSectionConfigElement details)
{
if (BaseIndexOf(details) >= 0)
BaseRemove(details.Id);
}
public void RemoveAt(int index)
{
BaseRemoveAt(index);
}
public void Remove(string name)
{
BaseRemove(name);
}
public void Clear()
{
BaseClear();
}
protected override string ElementName
{
get { return "DocumentationSection"; }
}
}
public class DocumentationSectionConfigElement : ConfigurationElement
{
[ConfigurationProperty("Id", IsRequired = true, IsKey = true)]
[StringValidator(InvalidCharacters = " ~!@#$%^&*()[]{}/;’\"|\\")]
public string Id
{
get { return (string)this["Id"]; }
set { this["Id"] = value; }
}
[ConfigurationProperty("Name", IsRequired = false)]
public string Name
{
get { return (string)this["Name"]; }
set { this["Name"] = value; }
}
[ConfigurationProperty("SectionDescription")]
public SectionDescription SectionDescription
{
get { return ((SectionDescription)base["SectionDescription"]); }
}
}
public class SectionDescriptionConfigElement : ConfigurationElement
{
[ConfigurationProperty("Value", IsRequired = true)]
public string Value
{
get { return (string)this["Value"]; }
set { this["Value"] = value; }
}
}