在很多.net开发的项目中,我们几乎都会使用到一些自定义的参数,比如说第三方的配置参数之类的.
他们的特点是:1.系统全局 2,可以做成键值对(Dictionary).
我们可以将这些参数放到Web.config,xml或者数据库表中,当然部分不常变的可以直接写在程序中.
为了方便我通常喜欢将他们统放在一个配置管理器中,然后希望别人使用时, 可以像使用AppSetings中的参数一样
初看起来还是比较容易实现,在ConfiguratonManager中定义一个公开属性AppSettings就好了.
实现如下:
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操作。
客户端测试一下:
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();
}
}
}
好像也能运行。
那么,问题来了!测试代码改一改,
//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 = ; i < ; 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 = ;
int.TryParse(Settings[key], out value);
return value;
}
}
大家看到代码简洁了不少,有了以下改进:
1.代码变少了
2.可以控制索引的返回结果了
3.更多的利用了Dictionary自身的特性,如CRUD
4.增加了自定义类型转换方法
总之,这些努力都是为了方便别人使用.
好吧,看看客户端测试吧
测试结果是OK的
好了,这样一个通用的配置管理器完成了, 当然有更多的需求,还可以对其进行扩展。欢迎大家不吝赐教 .
祝大家新年快乐,万事如意! 2015,一起任性!