我找到了a great example for custom configuration handler并试图将它用于我自己的实现.
我已经像这样设置了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’上收到错误,错误:无法识别的属性’Value’.我已经放了“public SectionDescription SectionDescription”,因为“DocumentationSectionConfigElement”类暴露了属性访问,但我可能错了,我先尝试将它放入“DocumentationSectionCollection”,但我不知道如何在那里实现它,对我来说似乎是“DocumentationSectionCollection”仅实现“集合”逻辑.
>我想要像这样访问“字段”:
section.Id
section.SectionDescription.Value
或者像这样:
section.Properties.Id
section.SectionDescription.Properties.Value
我看到“Collection”允许使用这样的索引器方法直接使用这些属性:
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>
当您需要更好地组织应用程序配置时,它更接近真实场景.
>如果“自定义配置处理程序”有效,“configSections”中的“sectionGroup”标记有什么意义,只要注册了一个“部分”就足够了?
>为什么所有这些东西都如此复杂?我花了这么多时间来处理这些“定制配置”的东西,我相信这些东西不应该那么复杂.是不是有任何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; }
}
}
解决方法:
由于此处没有活动,我将尝试逐一回答我的问题:
>找到了描述很多内容的this nice article,并展示了一些自定义配置实现的复杂示例.
>我找到了this great tool – “.NET Configuration Code Generator”,这正是我想要的 – 它采用XML结构并生成自定义配置代码.