在第一篇介紹過 App.config 的基本觀念,與第二篇說明了 App.config 的進階用法後,再來本篇沒有要說新的觀念,只是在前面兩篇中,我們看到一個愈複雜的 App.config,其後面伴隨著要寫許多程式碼。其實這些程式碼是可以簡化的,這邊限量就要來說明如何簡化使用 App.config 的程式碼。
我們簡化的觀念很簡單,就是使用泛型來動態決定處理的類別。
我們從第二篇的陣列範例來看,仔細的去發現程式碼的規律,可以發現到,繼承 ConfigurationElementCollection 的 Collection 類別只需要覆寫 2 個 Method 與實作 Index 就可以合法使用了,而且每個類別極度相似,只有在 Element 這邊是不同的,因此限量覺得在 Collection 的部分可以簡化。但是注意,GetElementKey 需要去指定 Element 的某個可當作 Key 的 Property,泛型的篩選條件就不能直接用最基本的 T 繼承 ConfigurationElement 來判斷,所以限量就實作一個抽象 Element 類別來解決這個問題。
ConfigEleBase.cs
再回頭看看 Collection 的程式如何簡化:
GenericConfigEleCollection.cs
GenericConfigEleCollection 只是把 Element 的部分改成 T,另外要加上 T 的篩選條件,T 繼承 ConfigEleBase。另外因為在這邊會產生 T 的實體,所以篩選條件後面要加 new()。
接著就來看看原本的程式要怎麼改:
只要將 CacheEle.cs 改成繼承 ConfigEleBase,並且將 Name 的 Property 刪掉。再來到 SettingSection.cs 中,把 CacheEleCollection 取代成 GenericConfigEleCollection<CacheEle> 就好了。改完了執行就可以發現結果是相同的。
CacheEle.cs
SettingSection.cs
看到這樣了如果還是嫌程式碼太多的話,好吧,其實我們從 Element 的類別看也可以看到很多規律,像是 Property 的 get set 實作方式, 加入的ConfigurationProperty, 繼承 ConfigurationElement...等,這些都是可以改善的。限量提供一個想法,就是可以利用 .Net 的動態建立型別的方式,我只要定義好一個 Element 類別的 Template,然後只要傳入要當作 Config 的資料結構,接著使用反射去取得資料結構的屬性,再來把這些屬性填入 Template 再 動態編譯就 OK 了。因為實作實在是太複雜了,所以就靠自己去發想吧,有機會限量再來分享。
站內相關文章:
C# - App.config自訂section程式碼架構Part I(基本用法)
C# - App.config自訂section程式碼架構Part II (巢狀, 陣列)
我們從第二篇的陣列範例來看,仔細的去發現程式碼的規律,可以發現到,繼承 ConfigurationElementCollection 的 Collection 類別只需要覆寫 2 個 Method 與實作 Index 就可以合法使用了,而且每個類別極度相似,只有在 Element 這邊是不同的,因此限量覺得在 Collection 的部分可以簡化。但是注意,GetElementKey 需要去指定 Element 的某個可當作 Key 的 Property,泛型的篩選條件就不能直接用最基本的 T 繼承 ConfigurationElement 來判斷,所以限量就實作一個抽象 Element 類別來解決這個問題。
ConfigEleBase.cs
public class ConfigEleBase : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get
{
return this["name"] as string;
}
set
{
this["name"] = value;
}
}
}
ConfigEleBase 是繼承 ConfigurationElement 的抽象類別,裏頭只有一個 Name 的 Property,因為是要讓 Collection 的 GetElementKey 當作 Key 的識別,所以這個 Name 就把它設置為 IsRequired = true。接著其他 Element 類別只要改繼承 ConfigEleBase 就可以了。再回頭看看 Collection 的程式如何簡化:
GenericConfigEleCollection.cs
public class GenericConfigEleCollection<T> : ConfigurationElementCollection where T : ConfigEleBase, new()
{
protected override ConfigurationElement CreateNewElement()
{
return new T();
}
protected override object GetElementKey(ConfigurationElement element)
{
return (element as T).Name;
}
public T this[int index]
{
get
{
return this.BaseGet(index) as T;
}
}
}
GenericConfigEleCollection 只是把 Element 的部分改成 T,另外要加上 T 的篩選條件,T 繼承 ConfigEleBase。另外因為在這邊會產生 T 的實體,所以篩選條件後面要加 new()。
接著就來看看原本的程式要怎麼改:
只要將 CacheEle.cs 改成繼承 ConfigEleBase,並且將 Name 的 Property 刪掉。再來到 SettingSection.cs 中,把 CacheEleCollection 取代成 GenericConfigEleCollection<CacheEle> 就好了。改完了執行就可以發現結果是相同的。
CacheEle.cs
public class CacheEle : ConfigEleBase
{
[ConfigurationProperty("path", IsRequired = true)]
public string Path
{
get
{
return this["path"] as string;
}
set
{
this["path"] = value;
}
}
[ConfigurationProperty("Global")]
public CacheGlobalEle Global
{
get
{
return this["Global"] as CacheGlobalEle;
}
}
[ConfigurationProperty("Session")]
public CacheSessionEle Session
{
get
{
return this["Session"] as CacheSessionEle;
}
}
}
SettingSection.cs
public class SettingSection : ConfigurationSection
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get
{
return this["name"] as string;
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("type", IsRequired = false)]
public string Type
{
get
{
return this["type"] as string;
}
set
{
this["type"] = value;
}
}
[ConfigurationProperty("Caches")]
[ConfigurationCollection(typeof(CacheEle), AddItemName = "Cache")]
public GenericConfigEleCollection<CacheEle> Caches
{
get
{
return this["Caches"] as GenericConfigEleCollection<CacheEle>;
}
}
}
看到這樣了如果還是嫌程式碼太多的話,好吧,其實我們從 Element 的類別看也可以看到很多規律,像是 Property 的 get set 實作方式, 加入的ConfigurationProperty, 繼承 ConfigurationElement...等,這些都是可以改善的。限量提供一個想法,就是可以利用 .Net 的動態建立型別的方式,我只要定義好一個 Element 類別的 Template,然後只要傳入要當作 Config 的資料結構,接著使用反射去取得資料結構的屬性,再來把這些屬性填入 Template 再 動態編譯就 OK 了。因為實作實在是太複雜了,所以就靠自己去發想吧,有機會限量再來分享。
站內相關文章:
C# - App.config自訂section程式碼架構Part I(基本用法)
C# - App.config自訂section程式碼架構Part II (巢狀, 陣列)
留言
張貼留言