Search code examples
c#.netcustom-configuration

How to read this custom configuration from App.config?


How to read this custom configuration from App.config?

<root name="myRoot" type="rootType">
    <element name="myName" type="myType" />
    <element name="hisName" type="hisType" />
    <element name="yourName" type="yourType" />
  </root>

Rather than this:

<root name="myRoot" type="rootType">
  <elements>
    <element name="myName" type="myType" />
    <element name="hisName" type="hisType" />
    <element name="yourName" type="yourType" />
  </elements>
  </root>

Solution

  • To enable your collection elements to sit directly within the parent element (and not a child collection element), you need to redefine your ConfigurationProperty. E.g., let's say I have a collection element such as:

    public class TestConfigurationElement : ConfigurationElement
    {
        [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
        public string Name
        {
            get { return (string)this["name"]; }
        }
    }
    

    And a collection such as:

    [ConfigurationCollection(typeof(TestConfigurationElement), AddItemName = "test")]
    public class TestConfigurationElementCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new TestConfigurationElement();
        }
    
        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((TestConfigurationElement)element).Name;
        }
    }
    

    I need to define the parent section/element as:

    public class TestConfigurationSection : ConfigurationSection
    {
        [ConfigurationProperty("", IsDefaultCollection = true)]
        public TestConfigurationElementCollection Tests
        {
            get { return (TestConfigurationElementCollection)this[""]; }
        }
    }
    

    Notice the [ConfigurationProperty("", IsDefaultCollection = true)] attribute. Giving it an empty name, and the setting it as the default collection allows me to define my config like:

    <testConfig>
      <test name="One" />
      <test name="Two" />
    </testConfig>
    

    Instead of:

    <testConfig>
      <tests>
        <test name="One" />
        <test name="Two" />
      </tests>
    </testConfig>