在C#類庫中使用App.config文件自定義配置


  做項目時,經常需要在自己設計的類庫中使用很多用戶配置。雖然在應用程序的App.config和Web應用程序web.config這樣的文件里配置也能滿足需求,但這樣做不僅會讓主配置文件的內容變得多、雜,還會讓模塊依賴主程序的配置文件。

  我們知道在VS中,可以在類庫項目里添加一種叫做“應用程序配置文件”的文件,這是標准的.NET配置文件,模板自帶“configuration”元素,編輯時還會有智能提示。但是怎么在程序代碼中使用寫在App.config里的配置呢?近日在網上搜了一通,卻一無所獲。於是只好自已動手!

  我以前做的一個項目里,用到過類型的實現方式。可以獲取在類庫App.config文件中“appSettings”和“conectionStrings”節添加的自定義配置,但是不能自定義配置節。從MSDN上了解到,要想在配置文件中自定義配置節,需要實現一個自定義的ConfigurationSection。兩下結合起來,想在類庫中用App.config徹底自定義配置的需求就可以實現了。

  現在分享出來,希望對看到這篇文章的朋友有所幫助。

  第一步:創建項目和類庫:

  新建一個Windows控制台應用程序“MyDemo”,然后再新建一個C#類庫“MyDemo.Config”,並在MyDemo中添加對MyDemo.Config的引用。

  第二步:添加引用,新建配置文件:

  在MyDemo.Config中先刪除除System之外的所有引用,然后添加對System.Configuration庫的引用,並新建一個配置文件App.config。

 

 

 

 

 

 


 

  第三步:在MyDemo.Config里面添加一個靜態類“ConfigManager”,代碼里這樣寫:

View Code
using System;
using System.Configuration;

namespace MyDemo.Config
{
    public static class ConfigManager
    {
        readonly static bool _Error;

        static Configuration _AppConfig;

        static ConfigManager()
        {
            string dllPath = string.Format(
                "{0}\\{1}.dll", AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory, "MyDemo.Config");

            try
            {
                _AppConfig = ConfigurationManager.OpenExeConfiguration(dllPath);
            }
            catch(ConfigurationErrorsException)
            {
                _Error = true;
            }
        }

        public static KeyValueConfigurationCollection AppSettings
        {
            get 
            {
                if (_Error) return null;
                return _AppConfig.AppSettings.Settings;
            }
        }

        public static ConnectionStringSettingsCollection ConnectionStrings
        {
            get
            {
                if (_Error) return null;
                return _AppConfig.ConnectionStrings.ConnectionStrings;
            }
        }
    }
}

  通過AppDomain.CurrentDomain.BaseDirectory和穩定的類庫名稱,來獲取實際運行中該dll文件的具體物理路徑,然后通過ConfigurationManager的OpenExeConfiguration方法就能獲取到相應的dll.config文件中的配置。

  為了保險起見,我增加了一個_Error字段,在靜態構造器中使用了try語句,這樣能保證程序的順序運行!

  通過這個ConfigManager,可以直接獲取在App.config中添加的appSeetings和connectionStrings的配置。

  第四步:添加對自定義的配置節的支持

  要自定義配置節,需要實現ConfigurationSection。這個其實MSDN上就有很好的例子,我這里做一個簡單的實現,比如我要增加這樣的配置:

<smtp host="smtp.163.com" mail="abc@163.com" pass="123456"></smtp>

  我們來新建一個SmtpSection,繼承自ConfigurationSection。重寫基類的IsReadOnly()方法,表示這些配置是只讀的。

  然后我們添加幾個只讀的屬性:Host(string)、Mail(string)、Password(string)、Port(int);get訪問器的實現很特殊,要用this["自定義配置節的attribute名稱"]這種方法,還要轉換成相應屬性的具體類型。所有將在配置中出現的屬性,都要加上ConfigurationProperty標記。

  來看具體的實現:

View Code
using System;
using System.Configuration;

namespace MyDemo.Config
{
    public class SmtpSection : ConfigurationSection
    {
        public override bool IsReadOnly()
        {
            return true;
        }

        [ConfigurationProperty("host", IsRequired = true)]
        public string Host
        {
            get { return this["host"] as string; }
        }

        [ConfigurationProperty("mail", IsRequired = true)]
        //[RegexStringValidator(可以在這里用正則驗證配置文件中的值是否正確)]
        public string Mail
        {
            get { return this["mail"] as string; }
        }

        [ConfigurationProperty("pass", IsRequired = true)]
        public string Password
        {
            get { return this["pass"] as string; }
        }

        [ConfigurationProperty("port", IsRequired = false, DefaultValue = 25)]
        [IntegerValidator(MaxValue = 65535, MinValue = 1)]
        public int Port
        {
            get { return (int)this["port"]; }
        }
    }
}

  可以看到,在聲明屬性的ConfigurationProperty標記時,不但可以指定此屬性將在配置文件中出現的的名稱,還可以指定默認值、是否必須屬性等。字符串還可以使用RegexStringValidator標記來驗證用戶輸入的配置是否合法;數字則可以用IntegerValidator來規定用戶輸入的數字范圍。最貼心的是這些合法性的驗證,都是在編譯時進行的,而不是在程序運行時。

  第五步:在App.Config中添加自定義配置節

  新增一個configSections節,在下面添加自定義的section,nam的值是下面的xml元素的開始和結束標記,type的值的格式是這樣的“自定義配置節類型的完全名稱(包括命名空間), 命名空間”。這里增加一個appSetting和connectionString以便稍后測試。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="smtp" type="MyDemo.Config.SmtpSection, MyDemo.Config" />
  </configSections>
  <smtp host="smtp.163.com" mail="abc@163.com" pass="123456"></smtp>
  <appSettings>
    <add key="domain" value="dream.net" />
  </appSettings>
  <connectionStrings>
    <add name="default" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|NORTHWND.MDF;Integrated Security=True;Connect Timeout=30" />
  </connectionStrings>
</configuration>

  第六步:修改ConfigManager,添加獲取自定義配置節smtp的方法

  給ConfigManager類增加一個方法,為了能最大限度的重用這個方法,我把方法寫成了泛型方法! GetSection<T>(string name);

    public static T GetSection<T>(string name) where T : ConfigurationSection
    {
        if (_Error) return null;
        return _AppConfig.GetSection(name) as T;
    }

  第七步:測試

  要想使這個配置起使用,前提是App.config文件必須以“dll名稱.dll.config”的文件名存在應用程序的執行目錄中。生成類庫的時候,在類庫的輸出目錄會自動生成這個配置文件,但是每次更新配置文件都要把配置文件復制一遍很麻煩。解決辦法就是,把App.config改名。比如上面提到的MyDemo.Config中的App.config就可以改成“MyDemo.Config.dll.config”,然后設置屬性“復制到輸出目錄”為“較新則復制”。這樣,每次修改配置文件后,只要重新生成,配置文件就會被自動復制到應用程序的執行目錄中。

  解決了這個問題,我們在MyDemo中寫一段代碼測試一下,因為ConfigManager的一些屬性和方法的返回值的類型位於System.Configuration命名空間,所以,要使用它必須在程序中也添加對System.Configuration的引用。當然,你也可以改變一下獲取appSettings和connectionStrings的方式,直接返回配置的值,而不是配置集合!

using MyDemo.Config;    
class Program { static void Main(string[] args) { Console.WriteLine(ConfigManager.AppSettings["domain"].Value); Console.WriteLine(ConfigManager.ConnectionStrings["default"].ConnectionString); var smtp = ConfigManager.GetSection<MyDemo.Config.SmtpSection>("smtp"); Console.WriteLine(smtp.Host); Console.WriteLine(smtp.Mail); Console.WriteLine(smtp.Password); Console.WriteLine(smtp.Port); Console.Read(); } }

  運行結果:

  

   通過結果,可以確定配置在config里面的設置都已經被順利的讀出來了;這是ConfigurationSection的實現,另外,如果要實現的配置具有復雜數據結構,還要根據需要實現ConfigurationElement,具體實現請參考MSDN的例子 http://msdn.microsoft.com/zh-cn/library/2tw134k3(v=vs.100).aspx

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

PS:可以對例子的ConfigManager做一些改造,使之成為項目配置存取模塊(Configuration是支持讀寫的)。另外,對於一些不想這么麻煩的懶人,我推薦一款免費的VS插件,叫“Configuration Section Designer”,安裝插件后會安裝一個配置節的設計模板,允許你像設計UML圖一樣設計你的配置,插件會幫你自動生成具體的實現,非常的實用。

Demo下載

查看有關Configuration Section Designer的信息


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM