title: Nested custom elements in app.config (C#)
body: <p>G'da to everyone,</p>
  
  <p>For hours I've been trying to figure how to read settings from <a href="http://pastebin.com/yuz7jLbQ" rel="noreferrer">app.config</a> file:</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt;
  &lt;configuration&gt;
  
    &lt;configSections&gt;
      &lt;section name="Databases" type="McFix.DatabaseSection, McFix"/&gt;
    &lt;/configSections&gt;
  
    &lt;Databases&gt;
      &lt;Database name="database"&gt;
        &lt;Tables&gt;
          &lt;Table name="be_sessions"&gt;
            &lt;Columns&gt;
              &lt;Column name="sess_id"&gt;
              &lt;/Column&gt;
            &lt;/Columns&gt;
          &lt;/Table&gt;
        &lt;/Tables&gt;
      &lt;/Database&gt;
    &lt;/Databases&gt;
  
    &lt;startup&gt;
      &lt;supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/&gt;
    &lt;/startup&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>The the code for custom handler classes is <a href="http://pastebin.com/ZAxQjySe" rel="noreferrer">here</a>, also copied below:</p>
  
  <pre><code>public class DatabaseSection : ConfigurationSection
  {
      [ConfigurationProperty("Databases", IsDefaultCollection = false)]
      public DatabaseInstanceCollection Databases
      {
          get { return (DatabaseInstanceCollection)this["Databases"]; }
          set { this[""] = value; }
      }
  }
  [ConfigurationCollection(typeof(DatabaseElement), AddItemName = "add", CollectionType = ConfigurationElementCollectionType.BasicMap )]
  public class DatabaseInstanceCollection : ConfigurationElementCollection
  {
      protected override ConfigurationElement CreateNewElement()
      {
          return new DatabaseElement();
      }
      protected override object GetElementKey(ConfigurationElement element)
      {
          return ((DatabaseElement)element).Name;
      }
  }
  public class DatabaseElement : ConfigurationElement
  {
      [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
      public string Name
      {
          get { return (string)base["name"]; }
          set { base["name"] = value; }
      }
  }
  
  public class TableSection : ConfigurationSection
  {
      [ConfigurationProperty("Tables", IsDefaultCollection = true)]
      public TableInstanceCollection Tables
      {
          get { return (TableInstanceCollection)this["Tables"]; }
          set { this[""] = value; }
      }
  }
  
  [ConfigurationCollection(typeof(TableElement), AddItemName = "Table", CollectionType = ConfigurationElementCollectionType.BasicMap)]
  public class TableInstanceCollection : ConfigurationElementCollection
  {
      protected override ConfigurationElement CreateNewElement()
      {
          return new TableElement();
      }
      protected override object GetElementKey(ConfigurationElement element)
      {
          return ((TableElement)element).Name;
      }
  }
  
  public class TableElement : ConfigurationElement
  {
      [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
      public string Name
      {
          get { return (string)base["name"]; }
          set { base["name"] = value; }
      }
  }
  
  public class ColumnSection : ConfigurationSection
  {
      [ConfigurationProperty("Columns", IsDefaultCollection = true)]
      public ColumnInstanceCollection Columns
      {
          get { return (ColumnInstanceCollection)this["Columns"]; }
          set { this[""] = value; }
      }
  }
  
  [ConfigurationCollection(typeof(ColumnElement), AddItemName = "Column", CollectionType = ConfigurationElementCollectionType.BasicMap)]
  public class ColumnInstanceCollection : ConfigurationElementCollection
  {
      protected override ConfigurationElement CreateNewElement()
      {
          return new ColumnElement();
      }
      protected override object GetElementKey(ConfigurationElement element)
      {
          return ((ColumnElement)element).Name;
      }
  }
  
  public class ColumnElement : ConfigurationElement
  {
      [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
      public string Name
      {
          get { return (string)base["name"]; }
          set { base["name"] = value; }
      }
  }
  </code></pre>
  
  <p>The problem is when I attempt to get "Databases" section via GetSection method:</p>
  
  <pre><code>Configuration Config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  DatabaseSection DbConfig = Config.GetSection("Databases") as DatabaseSection;
  </code></pre>
  
  <p>program throws an ConfigurationErrorsException, reporting "Unrecognized element 'Database'", although it does that after going through get method of DatabaseSection, even though I define AddItemName for DatabaseInstanceCollection as "Database". Am I missing something, attribute that will let underlying code read the app.config correctly?</p>