在不少.net開發的項目中,咱們幾乎都會使用到一些自定義的參數,好比說第三方的配置參數之類的.數據庫
他們的特色是:1.系統全局 2,能夠作成鍵值對(Dictionary).app
咱們能夠將這些參數放到Web.config,xml或者數據庫表中,固然部分不常變的能夠直接寫在程序中.ide
爲了方便我一般喜歡將他們統放在一個配置管理器中,而後但願別人使用時, 能夠像使用AppSetings中的參數同樣測試
初看起來仍是比較容易實現,在ConfiguratonManager中定義一個公開屬性AppSettings就行了.優化
實現以下:this
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConfigManager { public class ConfigurationContainer { private static ConfigurationContainer m_Instance = null; public static ConfigurationContainer Instance { get { if (m_Instance == null) m_Instance = new ConfigurationContainer(); return m_Instance; } } private ConfigurationContainer() { } private ReadOnlyDictionary<string, string> _configuration; private Dictionary<string, string> _mutableConfiguration; public ReadOnlyDictionary<string, string> Configuration { get { //TODO:check is newest or not in database?? if (_mutableConfiguration == null) Init(); _configuration = new ReadOnlyDictionary<string, string>(_mutableConfiguration); return _configuration; } } public bool Add(string key, string value) { bool bRet = false; if (!_mutableConfiguration.ContainsKey(key)) { _mutableConfiguration.Add(key, value); bRet = true; } return bRet; } public bool Update(string key, string value) { bool bRet = false; if (_mutableConfiguration.ContainsKey(key)) { _mutableConfiguration[key] = value; bRet = true; } return bRet; } public bool Remove(string key) { bool bRet = false; if (_mutableConfiguration.ContainsKey(key)) { _mutableConfiguration.Remove(key); bRet = true; } return bRet; } //private bool ConfigurationAllowed(string key, string value) //{ // // Put in your checks and balances // // here and return the appropriate result // return true; //} private void Init() { _mutableConfiguration = new Dictionary<string, string>(); _mutableConfiguration.Add("key", "value"); _mutableConfiguration.Add("key1", "value1"); _mutableConfiguration["key2"] = "value2"; } } }
ConfigurationContainer: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConfigManager { public class ConfigManager { private static IReadOnlyDictionary<string, string> _AppSettings = null; public static IReadOnlyDictionary<string, string> Appettings { get { //initial ensurer the newest _AppSettings = ConfigurationContainer.Instance.Configuration; return _AppSettings; } } //Exception:Violence to Add public static void BeNaughtyWithConfiguration() { IDictionary<string, string> convertToReadWrite = (IDictionary<string, string>)_AppSettings; //ConfigElement element = convertToReadWrite["key"]; //element.Value = "Haa Haa"; //Console.WriteLine(element.Value); //Console.WriteLine(convertToReadWrite["key"]); //Console.ReadLine(); convertToReadWrite.Add("Key12345", "xsds"); } public static bool Add(string key, string value) { return ConfigurationContainer.Instance.Add(key, value); } public static bool Update(string key, string value) { return ConfigurationContainer.Instance.Update(key, value); } public static bool Remove(string key) { return ConfigurationContainer.Instance.Remove(key); } } }
最底層是一個單例模式,並封裝了字典的CRUD操做。spa
客戶端測試一下:.net
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConfigManager { class Program { static void Main(string[] args) { var settings = ConfigManager.Appettings; foreach(var item in settings) { Console.WriteLine("key:{0},value:{1}",item.Key,item.Value); } var t1 = ConfigManager.Appettings["key1"]; //test add ConfigManager.Add("t","test"); //var t2 = ConfigManager.Appettings; //update ConfigManager.Update("t","test123"); //remove ConfigManager.Remove("t"); Console.ReadKey(); } } }
好像也能運行。3d
那麼,問題來了!測試代碼改一改,code
//test not item in Dictionary var t2 = ConfigManager.Appettings["luckyhu"];
代碼崩潰了,老兄!
其實上面的代碼可以知足通常的需求,可是對使用着來講,仍然不太方便.因此我和同事進一步優化了上述代碼.
如今變得更加簡潔了.
public class SettingManager : Dictionary<string, string> { private static SettingManager _Settings = null; public static SettingManager Settings { get { if (_Settings == null) _Settings = new SettingManager(); return _Settings; } } private SettingManager() { //Init Data //DataSoure:truely data here... for (int i = 0; i < 10; i++) { var key = String.Format("key{0}", i); var value = String.Format("value{0}", i); if (!this.Keys.Contains(key)) this.Add(key, value); } } public string this[string key] { get { if (!this.ContainsKey(key)) return String.Empty; return base[key]; } set { base[key] = value; } } public static bool GetBoolValue(string key) { bool value = false; bool.TryParse(Settings[key], out value); return value; } public static int GetIntValue(string key) { int value = 0; int.TryParse(Settings[key], out value); return value; } }
你們看到代碼簡潔了很多,有了如下改進:
1.代碼變少了
2.能夠控制索引的返回結果了
3.更多的利用了Dictionary自身的特性,如CRUD
4.增長了自定義類型轉換方法
總之,這些努力都是爲了方便別人使用.
好吧,看看客戶端測試吧
測試結果是OK的
好了,這樣一個通用的配置管理器完成了, 固然有更多的需求,還能夠對其進行擴展。歡迎你們不吝賜教 .
祝你們新年快樂,萬事如意! 2015,一塊兒任性!