組態檔 ConfigSection 的使用

不使用 appSettings,來建立有結構的 組態設定
這篇還只是剛開始
還要搭配 ConfigurationElementCollection + ConfigurationElement ,才會有比較完整的架構
後面還有機會可以接觸到 ConfigurationSectionCollection

因為看了各大神的教學,還是試了幾個小時,好不容易才試出來這裡面的規則
所以做個簡單的筆記分享一下

先看方案架構
我把要取用組態檔的 Class 放至另一個專案 LibData
要執行程式的專案為 ConfigurationDemo

ConfigurationDemo中的 App.config 內容如下

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="Demo1" type="ConfigurationDemo.LibData.DemoSection, LibData" />
    <section name="Demo2" type="ConfigurationDemo.LibData.DemoSection, LibData" />
    <section name="Demo3" type="ConfigurationDemo.LibData.DemoSection, LibData" />
  </configSections>
  <Demo1 ID="1" Name="本機" />
  <Demo2 ID="2" Name="測試機" />
  <Demo3 ID="3" Name="正式機" />
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>
</configuration>


透過 LibData 中設定的語法↓,就可以取出這種↑結構的內容

using System.Configuration;

namespace ConfigurationDemo.LibData
{
    public class DemoSection : ConfigurationSection
    {
        [ConfigurationProperty("ID")]
        public int ID
        {
            get { return (int)this["ID"]; }
            set { this["ID"] = value; }
        }

        [ConfigurationProperty("Name")]
        public string Name
        {
            get { return (string)this["Name"]; }
            set { this["Name"] = value; }
        }

        public string PrintContent()
        {
            return $"ID:{ID}\tName:{Name}";
        }
    }
}

記得讓 ConfigurationDemo 引用 LibData 
ConfigurationDemo > Program.cs 執行程式的語法 如下:

using ConfigurationDemo.LibData;
using System;
using System.Configuration;

namespace ConfigurationDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            DemoSection ds1 = ConfigurationManager.GetSection("Demo1") as DemoSection;
            DemoSection ds2 = ConfigurationManager.GetSection("Demo2") as DemoSection;
            DemoSection ds3 = ConfigurationManager.GetSection("Demo3") as DemoSection;

            Console.WriteLine(ds1.PrintContent());
            Console.WriteLine(ds2.PrintContent());
            Console.WriteLine(ds3.PrintContent());

            Console.ReadLine();
        }
    }
}


執行結果:


寫這種型式的組態檔其實蠻常見的,但是很容易漏掉細節導致執行時出現 Exception
Exception 提供的訊息,其實還蠻難懂,如果經驗不足,會很難 Debug

整理一些個人常犯的錯誤,或是值得注意的地方:

<configSections> 一定要放在 組態檔中 <configuration> 的第一順位,否則會看到以下的 Exception

<section name="Demo1" type="ConfigurationDemo.LibData.DemoSection, LibData" />
一定要放在 <configSections> 中
name:Demo1 對應 下方的 <Demo1 ID="1" Name="本機" />
            如果這個對應有問題會產生以下的 Excpetion


type ,左方:指定對應 class
                    格式為完整的 namespace.class
                    有時候 namespace 不會帶方案名稱,不要在這邊不小心加上方案名稱
                    如果指定錯誤,會出現以下 Exception


type ,右方:指定對應的 dll 主檔名
                    通常也就是 類別庫 專案名稱
                    如果指定錯誤,會出現以下 Exception

Program.cs 取值 GetSection("Demo1")
如果 Demo1 不小心打錯或是找不到對應的 組態,就會出現以下 Excpetion

在 class property 上方指定的  [ConfigurationProperty("ID")]
代表此 class property 所對應的 組態檔 property 

還可以增加 attribute,例如:[ConfigurationProperty("ID",IsRequired =true)]
可參考:msdn