West Wind Application Configuration 入門

這套類別庫用來讀寫應用程式組態檔很好用喔!

簡介

用 Google 搜了一下,沒發現介紹此套件的中文文章。也許是因為用法很簡單吧,直接看範例程式碼就能理解怎麼用。

此類別庫的名稱是 West Wind Application Configuration for .NET。作者 Rick Strahl 有寫一篇文章:Building a better .NET Application Configuration Class - revisited,從這篇文章便可快速上手。如須查閱完整的 API,也有線上文件可以參考,可說相當完整、專業。

存取應用程式組態檔,聽起來好像是小事一件,卻也是每一個應用程式不可或缺的(除了 hello world 這類簡單範例),而且其中還有不少「眉角」和重複瑣碎的地方要處理,例如:
  • 為了防止組態檔中漏掉了某些參數,讀取參數值的時候還要檢查取出的值是否為 null;若為 null,表示沒有指定,應用程式很可能需要賦予預設值。(註:關於 configuration items 的中文,有時我會用「組態項目」,有時會用「參數」這個聽起來不太正式且容易混淆的稱呼,只是個人習慣而已。以下可能交替使用這兩個名詞。)
  • 非字串類型的參數,例如數字、布林、日期時間等等,需要手動轉型,還得注意轉型失敗的問題。
  • 組態檔裡面的參數太多了,想要用個別的獨立區段來保存特定用途的參數,可是常常忘記自訂組態區段的 XML 要怎麼寫 Orz
  • 不只讀取組態檔的參數,我還需要寫回去....
  • 我想要把組態檔案中的參數改放到資料庫中,方便從後端直接改資料表中的數值來控制前端應用程式的行為。
凡此種種,我曾經為了減少這些重複瑣碎的 coding 工作,自己寫個簡陋的工具類別。但寫得不好,沒法全面解決上述問題,只是接近堪用程度。所以當同事跟我推薦它時,試了一下,發現還真是簡單好用,正是我一直想要的東西。

試看以下這段程式碼:
bool twoFactorAuthEnabled = false;
Boolean.TryParse(ConfigurationManager.AppSettings["TwoFactorAuthEnabled"], out twoFactorAuthEnabled);
if (twoFactorAuthEnabled) 
{
    // Do something.
}

如果可以這樣寫:
if (AppConfig.TwoFactorAuthEnabled) 
{
    // Do something.
}

不只少打一些字,還有 IntelliSense 提示、防止拼錯字的作用。想想看,一個應用程式可能包含多個 Class Library 專案,各專案可能都需要存取組態檔,如果到處都是 ConfigurationManager.AppSettings["參數名稱"],將來發現參數太多需要整理或改名時,不是很麻煩嗎?

基本用法

幾個重點:
  • 建立一個類別來代表你的應用程式組態,此類別必須繼承自 Westwind.Utilities.Configuration.AppConfiguration。為了方便說明,以下將此類別稱為「組態類別」。
  • 預設情況下,組態類別的名稱會成為應用程式組態檔案中的自訂區段名稱;若該區段不存在,則會自動建立。當然我們也可以使用
  • 組態類別中的各個公開屬性會對應到應用程式組態檔的組態項目,也就是說,存取這些屬性就等於是存取應用程式的組態項目。
  • 應用程式的組態通常只需要一份,讓各組件共用。所以最簡單的用法,就是將組態類別設計成 singleton

入門練習

Step 1: 建立組態類別

建立一個 Console Application 專案,利用 NuGet 為專案加入 West Wind Application Configuration 套件,如下圖:


在專案中加入一個新類別,類別名稱叫做 AppConfig。

前面的用法重點曾提過,組態類別必須繼承自特定的基礎類別,而類別的公開屬性就是對應到組態項目。所以 AppConfig.cs 程式碼大概會寫成這樣:

public class AppConfig : Westwind.Utilities.Configuration.AppConfiguration
{
    public int SendEmailDelay { get; set; }
    public DateTime StartTime { get; set; }
    public bool EncryptionEnabled { get; set; }
    public string EncryptionMethod { get; set; }
    public string Mail_SmtpHost { get; set; }

    public AppConfig()
    {
        // 如果組態檔中沒有定義這些參數,就會使用以下預設值.
        SendEmailDelay = 1000;
        StartTime = DateTime.Now;
        EncryptionEnabled = true;
        EncryptionMethod = "AES";
    }

    protected override void OnInitialize(Westwind.Utilities.Configuration.IConfigurationProvider provider, string sectionName, object configData)
    {
        sectionName = String.Empty;    // 預設的 sectionName 就是這個類別的名稱: 'AppConfig',這裡改寫成空字串,表示要使用 appSettings 區段.
        base.OnInitialize(provider, sectionName, configData);
    }
}

當組態檔中沒有定義組態項目,而在程式中需要提供預設值,你可以把預設值寫在組態類別的建構函式裡,就像上面這個範例那樣。

另外也請注意範例程式中的 OnInitialize 方法。在預設情況下,組態類別的名稱會成為應用程式組態檔案中的自訂區段名稱。因此,類別名稱 AppConfig 即表示應用程式組態檔案中應該會有一個 <AppConfig> 區段(而不是我們常用的 <appSettings>)。不過,在此範例中,我改寫了 OnInitialize 方法,把內定的 sectionName 改成空字串,這會使得 Westwind 組態類別採用預設的  <appSettings> 區段來保存組態項目。練習時,你可以試試把清除 sectionName 的那行程式碼註解掉,然後在完成底下兩個練習步驟之後,觀察應用程式組態檔的內容。

Step 2: 把組態類別的 instance 放在共用的靜態類別裡

方便起見,我們常會把一些共用變數放在一個靜態類別裡,類別名稱可能就叫做 App,或者 AppGlobals 或 AppContext(類似 HttpContext 的概念)。組態類別的 instance 也可以放在這個共用類別裡,像這樣:

public static class AppGlobals
{
    public static AppConfig Config { get; set; }

    static AppGlobals()
    {
        Config = new AppConfig();
        Config.Initialize();    // 這行不可少!
    }
}

Step 3: 存取組態項目

前面的準備工作一旦完成,往後要存取組態項目就簡單啦,如下圖:

如果要修改組態項目值,並回存至組態檔,只要呼叫組態類別的 Write 方法:

static void Main(string[] args)
{
    Console.WriteLine("Is encryption enabled: {0}", AppGlobals.Config.EncryptionEnabled);

    AppGlobals.Config.StartTime = DateTime.Now;
    AppGlobals.Config.Write();
}

執行此範例程式,然後到執行檔所在的目錄開啟應用程式組態檔,看一下內容,應該會看到所有組態項目都已經在組態檔案中了,而我們根本不曾手動編輯組態檔——這一切都由組態類別代勞了。是不是很方便呢?

Happy coding!

Post Comments

技術提供:Blogger.