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

时间:2015-04-26 21:19:33

标签: c# configuration app-config sections

我找到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);
}

First&#39; Console.WriteLine&#39;工作得很完美。

所以我有以下问题和实施相关的问题:

  1. 我在第二个&#39; Console.WriteLine&#39;上收到错误,错误:无法识别的属性&#39;值&#39;。我已经把#34; public SectionDescription SectionDescription&#34;自&#34; DocumentationSectionConfigElement&#34;类暴露了属性访问,但我可能错了,我首先尝试将其放入&#34; DocumentationSectionCollection&#34;但我不知道如何在那里实现它,对我来说似乎&#34; DocumentationSectionCollection&#34;只实现&#34; Collection&#34;逻辑。

  2. 我想访问&#34;字段&#34;要么两个都这样:

    section.Id section.SectionDescription.Value

  3. 或者像这样:

    section.Properties.Id
    section.SectionDescription.Properties.Value
    

    我看到&#34; Collection&#34;允许直接使用这样的索引器方法来使用这些属性:

    public DocumentationSectionConfigElement this[int index]
    

    但我无法在&#34; SectionDescription&#34;上实现索引器方法。 class,因为它是一个单独的部分而不是一个集合,所以这个&#34;属性&#34;访问字段时名称仍然存在。

    1. 为了能够在这些配置对象上使用LINQ,我需要添加什么? 我的意思是这样的:

      (documentationSettings.DocumentationSections.Sections)。选择(x =&gt; x.Id)

    2. 复杂的XML结构配置处理程序是否有很好的例子?从我发现的那些大多数都是这样简单的结构:

         

    3. 但没有像这样复杂结构的任何例子:

      <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>
      
      当您需要更好地组织应用程序配置时,

      更接近真实场景。

      1. &#34; sectionGroup&#34;有什么意义?标记在&#34; configSections&#34; if&#34;自定义配置处理程序&#34;工作,只需一个&#34;部分&#34;注册?

      2. 为什么所有这些东西都如此复杂?我花了这么多时间来定制配置&#34;我相信不应该这么复杂的事情。 Aren是否有任何Visual Studio加载项可以处理这些内容并根据XML配置结构生成代码?

      3. 这是我的配置处理程序实现:

        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; }
            }
        }
        

1 个答案:

答案 0 :(得分:6)

由于此处没有活动,我会尝试逐一回答我的问题:

  1. 找到了描述很多内容的this nice article,并展示了一些自定义配置实现的复杂示例。

  2. 我找到了this great tool - ".NET Configuration Code Generator",这正是我想要的 - 它采用XML结构并生成自定义配置代码。