最近在學(xué)習(xí).Net Core的過程中,發(fā)現(xiàn).Net Framework中常用的ConfigurationManager在Core中竟然被干掉了。
也能理解。Core中使用的配置文件全是Json,不像Framework使用的XML,暫時不支持也是能理解的,但是畢竟全局配置文件這種東西還挺重要的,閱讀了一些文章后目前有3個解決方案。
一、引入擴(kuò)展System.Configuration.ConfigurationManager
這個擴(kuò)展庫可以直接在Nuget中獲取。
使用方法和說明見.NET Core 2.0遷移技巧之web.config配置文件
讀取的文件類型和方法都跟.Net Framework中一致,而且僅需引入包就可以,瞬間很興奮有木有!
但是!在使用過過程中發(fā)現(xiàn)這個擴(kuò)展有問題。項(xiàng)目運(yùn)行過程中需修改我的app.config文件,對我項(xiàng)目中輸出的內(nèi)容沒有絲毫影響,Debug發(fā)現(xiàn)獲取到的值的確沒有變化。重啟項(xiàng)目都沒有用。只有把項(xiàng)目重新編譯才好使。
不知道是不是因?yàn)槲业拇蜷_方式不對,但是最終放棄這個方法。
二、引入擴(kuò)展Microsoft.Extensions.Options.ConfigurationExtensions
這個擴(kuò)展庫也可以直接在Nuget中獲取。
使用方法和說明見 ASP.NET Core實(shí)現(xiàn)類庫項(xiàng)目讀取配置文件
這個可以讀取application.json中的配置參數(shù),不再使用XML可以說很好的貼近Core的設(shè)計理念。
可惜,這個也有點(diǎn)美中不足的地方。首先跟上面的那個一樣,運(yùn)行時修改json文件讀取到的內(nèi)容不會改變,但是至少重啟項(xiàng)目可以修改,這個讓我欣慰很多。另外就是,這個方法采用的是反序列化的原理,也就是必須有一個跟配置文件對應(yīng)的實(shí)體類才可以,這個感覺比較雞肋,放棄。
三、自定義擴(kuò)展方法
這個是我這次說的重點(diǎn),要是前面兩個方法能滿足讀者你的需求,那么就沒有必要看下去。
廢話少說,先上代碼:
public class ConfigurationManager { /// <summary> /// 配置內(nèi)容 /// </summary> private static NameValueCollection _configurationCollection = new NameValueCollection(); /// <summary> /// 配置監(jiān)聽響應(yīng)鏈堆棧 /// </summary> private static Stack<KeyValuePair<string, FileSystemWatcher>> FileListeners = new Stack<KeyValuePair<string, FileSystemWatcher>>(); /// <summary> /// 默認(rèn)路徑 /// </summary> private static string _defaultPath = Directory.GetCurrentDirectory() + "http://appsettings.json"; /// <summary> /// 最終配置文件路徑 /// </summary> private static string _configPath = null; /// <summary> /// 配置節(jié)點(diǎn)關(guān)鍵字 /// </summary> private static string _configSection = "AppSettings"; /// <summary> /// 配置外連接的后綴 /// </summary> private static string _configUrlPostfix = "Url"; /// <summary> /// 最終修改時間戳 /// </summary> private static long _timeStamp = 0L; /// <summary> /// 配置外鏈關(guān)鍵詞,例如:AppSettings.Url /// </summary> private static string _configUrlSection { get { return _configSection + "." + _configUrlPostfix; } } static ConfigurationManager() { ConfigFinder(_defaultPath); } /// <summary> /// 確定配置文件路徑 /// </summary> private static void ConfigFinder(string Path) { _configPath = Path; JObject config_json = new JObject(); while (config_json != null) { config_json = null; FileInfo config_info = new FileInfo(_configPath); if (!config_info.Exists) break; FileListeners.Push(CreateListener(config_info)); config_json = LoadJsonFile(_configPath); if (config_json[_configUrlSection] != null) _configPath = config_json[_configUrlSection].ToString(); else break; } if (config_json == null || config_json[_configSection] == null) return; LoadConfiguration(); } /// <summary> /// 讀取配置文件內(nèi)容 /// </summary> private static void LoadConfiguration() { FileInfo config = new FileInfo(_configPath); var configColltion = new NameValueCollection(); JObject config_object = LoadJsonFile(_configPath); if (config_object == null || !(config_object is JObject)) return; if (config_object[_configSection]!=null) { foreach (JProperty prop in config_object[_configSection]) { configColltion[prop.Name] = prop.Value.ToString(); } } _configurationCollection = configColltion; } /// <summary> /// 解析Json文件 /// </summary> /// <param name="FilePath">文件路徑</param> /// <returns></returns> private static JObject LoadJsonFile(string FilePath) { JObject config_object = null; try { StreamReader sr = new StreamReader(FilePath, Encoding.Default); config_object = JObject.Parse(sr.ReadToEnd()); sr.Close(); } catch { } return config_object; } /// <summary> /// 添加監(jiān)聽樹節(jié)點(diǎn) /// </summary> /// <param name="info"></param> /// <returns></returns> private static KeyValuePair<string, FileSystemWatcher> CreateListener(FileInfo info) { FileSystemWatcher watcher = new FileSystemWatcher(); watcher.BeginInit(); watcher.Path = info.DirectoryName; watcher.Filter = info.Name; watcher.IncludeSubdirectories = false; watcher.EnableRaisingEvents = true; watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Size; watcher.Changed += new FileSystemEventHandler(ConfigChangeListener); watcher.EndInit(); return new KeyValuePair<string, FileSystemWatcher>(info.FullName, watcher); } private static void ConfigChangeListener(object sender, FileSystemEventArgs e) { long time = TimeStamp(); lock (FileListeners) { if (time > _timeStamp) { _timeStamp = time; if (e.FullPath != _configPath || e.FullPath == _defaultPath) { while (FileListeners.Count > 0) { var listener = FileListeners.Pop(); listener.Value.Dispose(); if (listener.Key == e.FullPath) break; } ConfigFinder(e.FullPath); } else { LoadConfiguration(); } } } } private static long TimeStamp() { return (long)((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds * 100); } private static string c_configSection = null; public static string ConfigSection { get { return _configSection; } set { c_configSection = value; } } private static string c_configUrlPostfix = null; public static string ConfigUrlPostfix { get { return _configUrlPostfix; } set { c_configUrlPostfix = value; } } private static string c_defaultPath = null; public static string DefaultPath { get { return _defaultPath; } set { c_defaultPath = value; } } public static NameValueCollection AppSettings { get { return _configurationCollection; } } /// <summary> /// 手動刷新配置,修改配置后,請手動調(diào)用此方法,以便更新配置參數(shù) /// </summary> public static void RefreshConfiguration() { lock (FileListeners) { //修改配置 if (c_configSection != null) { _configSection = c_configSection; c_configSection = null; } if (c_configUrlPostfix != null) { _configUrlPostfix = c_configUrlPostfix; c_configUrlPostfix = null; } if (c_defaultPath != null) { _defaultPath = c_defaultPath; c_defaultPath = null; } //釋放掉全部監(jiān)聽響應(yīng)鏈 while (FileListeners.Count > 0) FileListeners.Pop().Value.Dispose(); ConfigFinder(_defaultPath); } }}
新聞熱點(diǎn)
疑難解答
圖片精選