c# – App.config:自定义配置嵌套部分

我找到了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结构并生成自定义配置代码.

上一篇:.net core 13


下一篇:CodeForces-1132C-Painting the Fence-(前缀和)