通常在app.config
都是用原本預設的element
,不過,今天為了自己的元件的設定,必須透過客製化的element
作為元件的config,好久沒有研究這部分,所以,研究一下,終於被我弄出來,因此,在這紀錄一下,讓有後續想用的人可以參考
自訂.config標籤
這裡自訂標籤如下,主要標籤分為三層,第一層Token
為最外面標籤,等同於元件要開始讀取此設定的root位置,第二層TokenTarget
,定義為設定值得Group集合,在root
下,可以設定多個不同的Group,第三層target
就是我們要讀得設定參數
1 2 3 4 5 6
| <Token> <TokenTarget> <target type="File" IgnorePath="" TokenPath="" TokenDuration="10"/> <target type="DB" IgnorePath="" TokenDuration="10" connectionString=""></target> </TokenTarget> </Token>
|
而target
每個屬性都代表要給予的參數值,設定好自訂標籤的config,接下來就是要讀取標籤內的資料,Config內只設定這樣還不夠,還必須設定<configSections>
中註冊要讀取這客製化標籤的元件名稱,例如
1
| <section name="Token" type="CustomeXMLConfig.Token,CustomeXMLConfig" />
|
在這標籤中的name
設定的是自訂標籤的第一層名字也就是Token
,在type的設定格式,前者為namespace
+第一層的Class名稱,後者為namespace
,以這例子,namespace=CustomeXMLConfig,第一層的Class名稱是Token
讀取客製化Config標籤資料
在C#則是把XML的結構進行拆解,每一層其實都是一個物件,所以,先從最裡面的target
開始,可以訂定如下的Class,使用之前必須先參考System.Configuration
進來
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Target : ConfigurationElement { [ConfigurationProperty("type", IsRequired = true)] public string Type => (string)this["type"]; [ConfigurationProperty("IgnorePath", IsRequired = false)] public string IgnorePath => (string)this["IgnorePath"]; [ConfigurationProperty("TokenPath", IsRequired = false)] public string TokenPath => this["TokenPath"] == null ? "" : (string)this["TokenPath"]; [ConfigurationProperty("TokenDuration", IsRequired = false)] public int TokenDuration => (int)this["TokenDuration"]; [ConfigurationProperty("connectionString", IsRequired = false)] public string ConnectionString => this["connectionString"] == null ? "" : (string)this["connectionString"]; }
|
IsRequired
是代表這屬性是為必要,如果是必要,在XML設定中就必須放入值進去,在ConfigurationProperty
內定義要抓取在target
內的屬性標籤名字,所以,這部分可以稱做是Element
再來,就是第二層的TokenTarget
,這裡則稱為Collection
,在這裡必須告知在Collection裡面要抓的element名稱,必須給定是target
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| [ConfigurationCollection(typeof(Target))] public class TokenTarget : ConfigurationElementCollection { private const string PropertyName = "target"; public override ConfigurationElementCollectionType CollectionType => ConfigurationElementCollectionType.BasicMapAlternate; protected override string ElementName => PropertyName; protected override ConfigurationElement CreateNewElement() { return new Target(); } protected override object GetElementKey(ConfigurationElement element) { return ((Target) element).Type; } public Target this[int idx] => (Target)BaseGet(idx); }
|
其中,Target this[int idx] => (Target)BaseGet(idx)
這一段可以讓你在後續要使用時候,可以列出target
所具有的屬性
最後就是第一層的位置,如果在Collection只有一個TokenTarget
時候,這邊就可以直接設定要讀取Property為TokenTarget
物件,再由TokenTarget
物件帶出target
物件
1 2 3 4 5 6 7 8 9
| public class Token : ConfigurationSection { [ConfigurationProperty("TokenTarget")] public TokenTarget TokenTarget { get => ((TokenTarget) (this["TokenTarget"])); set => this["TokenTarget"] = value; } }
|
以上標籤對應的類別定義好之後,就可以去讀取它了,透過GetSection
取得root名稱下的標籤,這邊root名稱為Token
1
| var config = System.Configuration.ConfigurationManager.GetSection("Token");
|
抓出第二層的資訊
1
| var token = (config as Token).TokenTarget;
|
然後,再從第二層物件取得最後一層element的屬性
1 2 3 4 5
| for (int i = 0; i < token.Count; i++) { Console.WriteLine(token[i].Type); Console.WriteLine(token[i].TokenDuration.ToString()); }
|
就這樣就可以把我們想要客製化element中的設定檔讀出來了