[ASP.NET] 使用 configSections 自訂組態區段(web.config/app.config)

前言


  在某些情況下我們可能會需要自定義組態檔(web.config / app.config)的設定,例如某些參數放在組態檔中取得或者使用依賴注入時用來定義類別等等...那實際上要怎麼去定義呢? 讓我們繼續看下去。

範例


Step 1 建立ConfigurationSection類別

先介紹幾個類別詞兒:
  • ConfigurationSection : 代表組態中的區段,將會對應到組態檔中的 configSections 區段標簽。
  • ConfigurationSectionCollection : 代表組態檔中相關區段的集合。
  • ConfigurationElementCollection : 代表組態檔中相關項目的集合,例如可能定義一個A底下有A1,A2,A3。
  • ConfigurationElement : 代表組態檔中的項目,也就通常最後設定屬性的那個標簽。
  • ConfigurationProperty : Attribute,用來設定屬性或項目的子系。

大概了解以上這些類別功用後就要開始建立對應的類別讓之後能夠讀取操作,依照設定檔巢狀的關係將建立以下類別,首先專案必須加入System.Configuration參考並using System.Configuration命名空間。

1.建立TypeAliasesConfigurationElement類別並繼承ConfigurationElement後設定屬性

因之後我的設定字串需要使用到 name 跟 type 屬性,宣告 Name 與 Type 兩個 Property並且使用ConfigurationProperty設定屬性IsRequired標示為需要的屬性,如下:
namespace TConfigurationSection.Configuration
{
    public class TypeAliasesConfigurationElement : ConfigurationElement
    {
        [ConfigurationProperty("name", IsRequired = true)]
        public string Name { get { return base["name"].ToString(); } }
        [ConfigurationProperty("type", IsRequired = true)]
        public string Type { get { return base["type"].ToString(); } }
    }
}

2.建立TypeAliasesConfigurationElementCollection類別並繼承ConfigurationElementCollection

因之後項目是多個的所以使用Collection包裝,必須實作CreateNewElement及GetElementKey成員,在CreateNewElement方法中要回傳建立一個TypeAliasesConfigurationElement類別,在GetElementKey方法中要回傳一個Key Name,也就是TypeAliasesConfigurationElement定義的Name屬性,如下:
namespace TConfigurationSection.Configuration
{
    public class TypeAliasesConfigurationElementCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new TypeAliasesConfigurationElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return (element as TypeAliasesConfigurationElement).Name;
        }
    }
}

3.建立TypeAliasesConfigurationSection類別並繼承ConfigurationSection

在此就是組態設定的區段定義,typeAliases將對應組態檔該Section的標簽
namespace TConfigurationSection.Configuration
{
    public class TypeAliasesConfigurationSection : ConfigurationSection
    {
        [ConfigurationProperty("typeAliases", IsKey = false, IsRequired = true)]
        [ConfigurationCollection(typeof(TypeAliasesConfigurationElementCollection),
            CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)]
        public TypeAliasesConfigurationElementCollection TypeAliasesClientConfigurations { 
            get { return base["typeAliases"] as TypeAliasesConfigurationElementCollection; } 
        }
    }
}

Step 2  增加組態檔定義區段

首先,要在組態中增加一個 configSections 區段,configSections 區段是用來定義之後要加入的 section,大至上設定格式如下:
<configuration>
  <configSections>
    <section name="TestConfig" type="TConfigurationSection.Configuration.TypeAliasesConfigurationSection, TConfigurationSection" />
  </configSections>
  <TestConfig>
    <typeAliases>
      <add name="Class1" type="TConfigurationSection.WorkClass, TConfigurationSection" />
      <add name="Class2" type="TConfigurationSection.WorkClass, TConfigurationSection" />
    </typeAliases>
  </TestConfig>
</configuration>
configSections的secton標籤的name屬性名稱必須要跟之後指定的secton區段標簽名稱一樣。
準備都完成後就可以實際來測試看看,使用以下程式碼可以取得設定並且使用:
static void Main(string[] args)
{
    Configuration.TypeAliasesConfigurationSection clientConfiguration = ConfigurationManager.GetSection("TestConfig") as
                                                                      Configuration.TypeAliasesConfigurationSection;

    foreach (Configuration.TypeAliasesConfigurationElement configElement in
                            clientConfiguration.TypeAliasesClientConfigurations)
    {
        Console.WriteLine(configElement.Name + "," + configElement.Type);
        Type oType = Type.GetType(configElement.Type.Split(',')[0] + "." + configElement.Name);
        object instance = Activator.CreateInstance(oType);
        oType.InvokeMember("Work", System.Reflection.BindingFlags.InvokeMethod, null, instance, new object[] { });
    }
    Console.ReadKey();
}

結果畫面:


以上就是自定組態區段的使用方式,另外想請問一下,是否有方法可以直接使用屬性的type,來轉換取得的型別呢? 就是不用 Type.GetType(clientConfigurationElement.Type.Split(',')[0] + "." + clientConfigurationElement.Name); 這樣的方式拆字串的方式。
是否有大大能提供意見指導,謝謝。

範例程式碼



參考資料






資料來源: https://dotblogs.com.tw/joysdw12/archive/2012/11/27/85181.aspx

留言

這個網誌中的熱門文章

[C#]Windows 10 停用與啟用網路卡(連線)[手把手教程][原創]

ASP.NET Web API 將傳回的值轉換從控制器動作至 HTTP 回應訊息的方式。

[C#]程式更改電腦IP位置與電腦名稱