[C#.NET] 如何自訂 Configuration Section

[C#.NET] 如何自訂 Configuration Section

.NET 的組態檔(App.config |Web.config)內建提供一些區段,它可以讓我們存放應用程式的參數: userSettings、applicationSettings,使用方式是透過 Properties.Settings.Default 存取,請參考

http://www.dotblogs.com.tw/yc421206/archive/2009/04/14/8000.aspx

http://www.dotblogs.com.tw/yc421206/archive/2010/08/08/17076.aspx

 

還有兩個區段 appSettings、connectionStrings ,這也是蠻常用的,主要是透過 ConfigurationManager 來存取

ConfigurationManager.AppSettings

ConfigurationManager.ConnectionStrings

它們的操作方式都相當的簡單,這也不是本篇的重點,就不在此多說明

為什麼需要自訂組態檔? 原因很簡單,在一個系統裡面,一但過多的參數擠在同一個區,參數太多就會顯得不易閱讀,自訂 Configuration 就是為了要抽離內建的區段,讓開發人員專注在特定區段內,如果你想要讓你的組態檔更好維護,可以繼續往下閱讀

本文章節:

ConfigurationSection

ConfigurationElement

ConfigurationSectionGroup

ConfigurationElementCollection


開始之前我們要先參考 System.Configuration.dll

ConfigurationSection

  1. 實作ConfigurationSection,Property(屬性)上加上 ConfigurationProperty Attribute,請依自己的需求設定
    https://msdn.microsoft.com/zh-tw/library/system.configuration.configurationpropertyattribute%28v=vs.110%29.aspx
  2. [ConfigurationProperty("Code")],Code代表在組態檔內的 section 的名稱
public class MySection : ConfigurationSection 
{ 
    private MySection() 
    { 
    }

    [ConfigurationProperty("Code", DefaultValue = "9527")] 
    public string Code 
    { 
        get { return this["Code"].ToString(); } 
        set { this["Code"] = value; } 
    }

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

}

ConfigurationElement

實作 ConfigurationElement,它是用來表示 Section 的成員,跟 Section 一樣,在屬性上面要加上 ConfigurationProperty Attribute

public class MemberElement : ConfigurationElement 
{ 
    [ConfigurationProperty("Id", DefaultValue = 2)] 
    public int Id 
    { 
        get { return (int)this["Id"]; } 
        set { this["Id"] = value; } 
    }

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


如此一來我們的組態類別算是準備完成了!!!接下來要設定組態檔 app.config | web.config

首先在.config 的 configSections 加入以下,其中 Simple.CustomConfiguration.MySection 是完整的類別名稱,Simple.CustomConfiguration 是組件名稱

<section name="MySection" type="Simple.CustomConfiguration.MySection, Simple.CustomConfiguration" />

依照剛剛定義的 section name 加入相關屬性

<MySection Code="23"> 
  <Member Id="2" Name="余小章" /> 
</MySection>

最後完整的.config 如下:

<?xml version="1.0" encoding="utf-8" ?>

<configuration> 
  <configSections> 
    <section name="MySection" type="Simple.CustomConfiguration.MySection, Simple.CustomConfiguration" /> 
  </configSections> 
  <MySection Code="23"> 
    <Member Id="2" Name="余小章" /> 
  </MySection> 
</configuration>

用戶端則是使用 ConfigurationManager.GetSection("MySection") 來取得剛剛自訂的 section

[TestMethod] 
public void SectionTestMethod() 
{ 
    var config = (MySection)ConfigurationManager.GetSection("MySection"); 
    Assert.AreEqual("23", config.Code); 
    Assert.AreEqual(2, config.Member.Id); 
    Assert.AreEqual("余小章", config.Member.Name); 
}


ConfigurationSectionGroup

接下來是 SectionGroup,主要是將 section 設為群組,這裡是實作 ConfigurationSectionGroup

public class MySectionGroup : ConfigurationSectionGroup 
{ 
    [ConfigurationProperty("Section1")] 
    public MySection MySection1 
    { 
        get { return (MySection)this.Sections["Section1"]; } 
    }

    [ConfigurationProperty("Section2")] 
    public MySection MySection2 
    { 
        get { return (MySection)this.Sections["Section2"]; } 
    } 
}

在.config裡,設定 sectionGroup

<?xml version="1.0" encoding="utf-8" ?>

<configuration> 
  <configSections> 
    <section name="MySection" type="Simple.CustomConfiguration.MySection, Simple.CustomConfiguration" /> 
    <sectionGroup name="MySectionGroup" type="Simple.CustomConfiguration.MySectionGroup,Simple.CustomConfiguration"> 
      <section name="MySection1" type="Simple.CustomConfiguration.MySection,Simple.CustomConfiguration" /> 
      <section name="MySection2" type="Simple.CustomConfiguration.MySection,Simple.CustomConfiguration" /> 
    </sectionGroup> 
  </configSections>

  <MySection Code="23"> 
    <Member Id="2" Name="余小章" /> 
  </MySection>

  <MySectionGroup> 
    <MySection1 Code="9571"> 
      <Member Id="1" Name="MySection1" /> 
    </MySection1> 
    <MySection2 Code="9572"> 
      <Member Id="2" Name="MySection2" /> 
    </MySection2> 
  </MySectionGroup> 
</configuration>

用戶端調用,用法跟 section 差不多,差別在於要給 group 位置

[TestMethod] 
public void SectoinGroupTestMethod() 
{ 
    var config1 = (MySection)ConfigurationManager.GetSection("MySectionGroup/MySection1"); 
    var config2 = (MySection)ConfigurationManager.GetSection("MySectionGroup/MySection2");

    Assert.AreEqual("9571", config1.Code); 
    Assert.AreEqual(1, config1.Member.Id); 
    Assert.AreEqual("MySection1", config1.Member.Name);

    Assert.AreEqual("9572", config2.Code); 
    Assert.AreEqual(2, config2.Member.Id); 
    Assert.AreEqual("MySection2", config2.Member.Name); 
}

ConfigurationElementCollection

這能讓我們在Configuration裡面使用集合,步驟如下

實作ConfigurationElementCollection,並覆寫以下行為

ConfigurationElement

  1. GetElementKey
  2. 這裡並不想要處理集合類別應有的 CRUD 行為,若需要的話可以自行加入
public class MemberElementCollection : ConfigurationElementCollection 
{ 
    public MemberElement this[int index] 
    { 
        get { return (MemberElement)this.BaseGet(index); } 
    }

    protected override ConfigurationElement CreateNewElement() 
    { 
        return new MemberElement(); 
    }

    protected override object GetElementKey(ConfigurationElement element) 
    { 
        return ((MemberElement)element).Id; 
    } 
}

 

在MySection類別,加入Members屬性

public class MySection : ConfigurationSection 
{ 
….

    [ConfigurationProperty("Members"), 
     ConfigurationCollection(typeof(MemberElement))] 
    public MemberElementCollection Members 
    { 
        get { return this["Members"] as MemberElementCollection; } 
        set { this["Members"] = value; } 
    } 
}

在.config,Members 區段設定如下:

<?xml version="1.0" encoding="utf-8" ?>

<configuration> 
  <configSections> 
    <section name="MySection" type="Simple.CustomConfiguration.MySection, Simple.CustomConfiguration" />

    <sectionGroup name="MySectionGroup" type="Simple.CustomConfiguration.MySectionGroup,Simple.CustomConfiguration"> 
      <section name="MySection1" type="Simple.CustomConfiguration.MySection,Simple.CustomConfiguration" /> 
      <section name="MySection2" type="Simple.CustomConfiguration.MySection,Simple.CustomConfiguration" /> 
    </sectionGroup> 
  </configSections>

  <MySection Code="23"> 
    <Member Id="2" Name="余小章" />

    <Members> 
      <add Id="1" Name="Yao1"></add> 
      <add Id="2" Name="Yao2"></add> 
      <add Id="3" Name="Yao3"></add> 
    </Members> 
  </MySection>

  <MySectionGroup> 
    <MySection1 Code="9571"> 
      <Member Id="1" Name="MySection1" /> 
    </MySection1> 
    <MySection2 Code="9572"> 
      <Member Id="2" Name="MySection2" /> 
    </MySection2> 
  </MySectionGroup> 
</configuration>

用戶端調用

[TestMethod] 
public void MembersTestMethod() 
{ 
    var config = (MySection)ConfigurationManager.GetSection("MySection");

    Assert.AreEqual(1, config.Members[0].Id); 
    Assert.AreEqual("Yao1", config.Members[0].Name); 
}

文章出自:http://www.dotblogs.com.tw/yc421206/archive/2015/06/20/151599.aspx

專案位置:https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.CustomConfiguration/

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo