Net Core全局配置讀取管理方法ConfigurationManager
最近在學(xué)習(xí).Net Core的過(guò)程中,發(fā)現(xiàn).Net Framework中常用的ConfigurationManager在Core中竟然被干掉了。
也能理解。Core中使用的配置文件全是Json,不像Framework使用的XML,暫時(shí)不支持也是能理解的,但是畢竟全局配置文件這種東西還挺重要的,閱讀了一些文章后目前有3個(gè)解決方案。
一、引入擴(kuò)展System.Configuration.ConfigurationManager
這個(gè)擴(kuò)展庫(kù)可以直接在Nuget中獲取。
使用方法和說(shuō)明見(jiàn).NET Core 2.0遷移技巧之web.config配置文件
讀取的文件類型和方法都跟.Net Framework中一致,而且僅需引入包就可以,瞬間很興奮有木有!
但是!在使用過(guò)過(guò)程中發(fā)現(xiàn)這個(gè)擴(kuò)展有問(wèn)題。項(xiàng)目運(yùn)行過(guò)程中需修改我的app.config文件,對(duì)我項(xiàng)目中輸出的內(nèi)容沒(méi)有絲毫影響,Debug發(fā)現(xiàn)獲取到的值的確沒(méi)有變化。重啟項(xiàng)目都沒(méi)有用。只有把項(xiàng)目重新編譯才好使。
不知道是不是因?yàn)槲业拇蜷_方式不對(duì),但是最終放棄這個(gè)方法。
二、引入擴(kuò)展Microsoft.Extensions.Options.ConfigurationExtensions
這個(gè)擴(kuò)展庫(kù)也可以直接在Nuget中獲取。
使用方法和說(shuō)明見(jiàn) ASP.NET Core實(shí)現(xiàn)類庫(kù)項(xiàng)目讀取配置文件
這個(gè)可以讀取application.json中的配置參數(shù),不再使用XML可以說(shuō)很好的貼近Core的設(shè)計(jì)理念。
可惜,這個(gè)也有點(diǎn)美中不足的地方。首先跟上面的那個(gè)一樣,運(yùn)行時(shí)修改json文件讀取到的內(nèi)容不會(huì)改變,但是至少重啟項(xiàng)目可以修改,這個(gè)讓我欣慰很多。另外就是,這個(gè)方法采用的是反序列化的原理,也就是必須有一個(gè)跟配置文件對(duì)應(yīng)的實(shí)體類才可以,這個(gè)感覺(jué)比較雞肋,放棄。
三、自定義擴(kuò)展方法
這個(gè)是我這次說(shuō)的重點(diǎn),要是前面兩個(gè)方法能滿足讀者你的需求,那么就沒(méi)有必要看下去。
廢話少說(shuō),先上代碼:
public class ConfigurationManager
{
/// <summary>
/// 配置內(nèi)容
/// </summary>
private static NameValueCollection _configurationCollection = new NameValueCollection();
/// <summary>
/// 配置監(jiān)聽(tīng)響應(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() + "\\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>
/// 最終修改時(shí)間戳
/// </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)聽(tīng)樹節(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>
/// 手動(dòng)刷新配置,修改配置后,請(qǐng)手動(dòng)調(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)聽(tīng)響應(yīng)鏈
while (FileListeners.Count > 0)
FileListeners.Pop().Value.Dispose();
ConfigFinder(_defaultPath);
}
}
}
最開始設(shè)計(jì)的是采用緩存,每次調(diào)用比對(duì)文件的修改時(shí)間,大小等特征,出現(xiàn)變化從新載入配置。后來(lái)發(fā)現(xiàn)圖樣圖森破!
C#提供了專門監(jiān)聽(tīng)文件系統(tǒng)的方法。所以從新設(shè)計(jì)了監(jiān)聽(tīng)響應(yīng)鏈堆棧來(lái)實(shí)現(xiàn)。
使用說(shuō)明:
1、配置節(jié)點(diǎn):
可以直接寫在項(xiàng)目默認(rèn)的配置文件appsettings.json中 格式如下
{
"AppSettings": {
"Title": "Test",
"Version": "1.2.1",
"AccessToken": "123456@abc.com"
}
}
保證配置節(jié)點(diǎn)AppSettings存在,剩下的就是以Key-Value的形式來(lái)寫屬性,就可以。
2、外部配置文件
像.Net Framework中一樣,可以通過(guò)外部配置文件來(lái)實(shí)現(xiàn)。格式如下
{
"AppSettings.Url": "D:\\test\\app1.json"
}
采用格式是“配置節(jié)點(diǎn)名.外鏈后綴”的形式。可以設(shè)計(jì)多級(jí)外部配置文件,只要發(fā)現(xiàn)有外部配置節(jié)點(diǎn)就會(huì)向下尋找,并監(jiān)聽(tīng)鏈上的所有節(jié)點(diǎn)文件的變化。
但是需要注意的是:一旦存在外部配置節(jié)點(diǎn),此文件中的配置節(jié)點(diǎn)和參數(shù)將不再參與解析
3、可配置初始化參數(shù)
包括默認(rèn)文件路徑在內(nèi)的多個(gè)參數(shù)均可以修改,詳情見(jiàn)代碼。
修改后需要手動(dòng)調(diào)用RefreshConfiguration方法,以使配置內(nèi)容生效,有點(diǎn)像事務(wù)處理。建議在項(xiàng)目的Startup方法中修改配置方法。
4、使用
跟.Net Framework中一樣,直接調(diào)用ConfigurationManager.Appsettings["Title"]就可以了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- ASP.NET?Core中的Configuration配置二
- ASP.NET?Core中的Configuration配置一
- 淺析.netcore中的Configuration具體使用
- ASP.NET Core Web API 教程Project Configuration
- .Net Core配置Configuration具體實(shí)現(xiàn)
- 如何在ASP.NET Core 的任意類中注入Configuration
- .Net Core3.0 配置Configuration的實(shí)現(xiàn)
- .NET Core 3.0之創(chuàng)建基于Consul的Configuration擴(kuò)展組件
- 詳解ASP.NET Core實(shí)現(xiàn)強(qiáng)類型Configuration讀取配置數(shù)據(jù)
相關(guān)文章
asp.net使用jquery實(shí)現(xiàn)搜索框默認(rèn)提示功能
這篇文章主要介紹了asp.net使用jquery實(shí)現(xiàn)搜索框默認(rèn)提示功能,大家參考使用吧2014-01-01
C# javaScript函數(shù)的相互調(diào)用
如何在JavaScript訪問(wèn)C#函數(shù),如何在C#中訪問(wèn)JavaScript的已有變量等實(shí)現(xiàn)方法2008-12-12
使用.NET Core創(chuàng)建exe應(yīng)用程序
這篇文章介紹了使用.NET Core創(chuàng)建exe應(yīng)用程序的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
ASP.NET中在一般處理程序中使用session的簡(jiǎn)單介紹
這篇文章介紹了ASP.NET中在一般處理程序中使用session,有需要的朋友可以參考一下2013-10-10
ASP.NET技巧:做個(gè)DataList可分頁(yè)的數(shù)據(jù)源
ASP.NET技巧:做個(gè)DataList可分頁(yè)的數(shù)據(jù)源...2006-09-09
asp.net 模擬提交有文件上傳的表單(通過(guò)http模擬上傳文件)
通過(guò)HTTP模擬GET或POST請(qǐng)求,提交數(shù)據(jù)到服務(wù)端獲取響應(yīng),比較常見(jiàn)些;但如上傳文件到服務(wù)端,使用html form當(dāng)然簡(jiǎn)單了,而因環(huán)境所限有時(shí)需要使用模擬方法去提交有附件(文件上傳)的表單。2010-02-02
ASP.NET頁(yè)面某些選項(xiàng)進(jìn)行提示判斷具體實(shí)現(xiàn)
針對(duì)asp.net頁(yè)面某些選項(xiàng)進(jìn)行提示判斷,比如當(dāng)保存一個(gè)信息時(shí)候,需要對(duì)當(dāng)前信息是否為空進(jìn)行判斷2013-06-06

