最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

Net Core全局配置读取管理方法ConfigurationManager

来源:懂视网 责编:小采 时间:2020-11-27 22:34:59
文档

Net Core全局配置读取管理方法ConfigurationManager

Net Core全局配置读取管理方法ConfigurationManager:最近在学习.Net Core的过程中,发现.Net Framework中常用的ConfigurationManager在Core中竟然被干掉了。 也能理解。Core中使用的配置文件全是Json,不像Framework使用的XML,暂时不支持也是能理解的,但是毕竟全局配置文件这种东西还挺重要的,阅读了一些文章
推荐度:
导读Net Core全局配置读取管理方法ConfigurationManager:最近在学习.Net Core的过程中,发现.Net Framework中常用的ConfigurationManager在Core中竟然被干掉了。 也能理解。Core中使用的配置文件全是Json,不像Framework使用的XML,暂时不支持也是能理解的,但是毕竟全局配置文件这种东西还挺重要的,阅读了一些文章

最近在学习.Net Core的过程中,发现.Net Framework中常用的ConfigurationManager在Core中竟然被干掉了。

也能理解。Core中使用的配置文件全是Json,不像Framework使用的XML,暂时不支持也是能理解的,但是毕竟全局配置文件这种东西还挺重要的,阅读了一些文章后目前有3个解决方案。

一、引入扩展System.Configuration.ConfigurationManager

这个扩展库可以直接在Nuget中获取。

使用方法和说明见.NET Core 2.0迁移技巧之web.config配置文件

读取的文件类型和方法都跟.Net Framework中一致,而且仅需引入包就可以,瞬间很兴奋有木有!

但是!在使用过过程中发现这个扩展有问题。项目运行过程中需修改我的app.config文件,对我项目中输出的内容没有丝毫影响,Debug发现获取到的值的确没有变化。重启项目都没有用。只有把项目重新编译才好使。

不知道是不是因为我的打开方式不对,但是最终放弃这个方法。

二、引入扩展Microsoft.Extensions.Options.ConfigurationExtensions

这个扩展库也可以直接在Nuget中获取。

使用方法和说明见 ASP.NET Core实现类库项目读取配置文件

这个可以读取application.json中的配置参数,不再使用XML可以说很好的贴近Core的设计理念。

  可惜,这个也有点美中不足的地方。首先跟上面的那个一样,运行时修改json文件读取到的内容不会改变,但是至少重启项目可以修改,这个让我欣慰很多。另外就是,这个方法采用的是反序列化的原理,也就是必须有一个跟配置文件对应的实体类才可以,这个感觉比较鸡肋,放弃。

三、自定义扩展方法

这个是我这次说的重点,要是前面两个方法能满足读者你的需求,那么就没有必要看下去。

废话少说,先上代码:

public class ConfigurationManager
 {
 /// <summary>
 /// 配置内容
 /// </summary>
 private static NameValueCollection _configurationCollection = new NameValueCollection();

 /// <summary>
 /// 配置监听响应链堆栈
 /// </summary>
 private static Stack<KeyValuePair<string, FileSystemWatcher>> FileListeners = new Stack<KeyValuePair<string, FileSystemWatcher>>();

 /// <summary>
 /// 默认路径
 /// </summary>
 private static string _defaultPath = Directory.GetCurrentDirectory() + "\\appsettings.json";

 /// <summary>
 /// 最终配置文件路径
 /// </summary>
 private static string _configPath = null;

 /// <summary>
 /// 配置节点关键字
 /// </summary>
 private static string _configSection = "AppSettings";

 /// <summary>
 /// 配置外连接的后缀
 /// </summary>
 private static string _configUrlPostfix = "Url";

 /// <summary>
 /// 最终修改时间戳
 /// </summary>
 private static long _timeStamp = 0L;

 /// <summary>
 /// 配置外链关键词,例如: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>
 /// 读取配置文件内容
 /// </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>
 /// 添加监听树节点
 /// </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>
 /// 手动刷新配置,修改配置后,请手动调用此方法,以便更新配置参数
 /// </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; }
 //释放掉全部监听响应链
 while (FileListeners.Count > 0)
 FileListeners.Pop().Value.Dispose();
 ConfigFinder(_defaultPath);
 }
 }

} 

最开始设计的是采用缓存,每次调用比对文件的修改时间,大小等特征,出现变化从新载入配置。后来发现图样图森破!

C#提供了专门监听文件系统的方法。所以从新设计了监听响应链堆栈来实现。

使用说明:

1、配置节点:

可以直接写在项目默认的配置文件appsettings.json中 格式如下

{
 "AppSettings": {
 "Title": "Test",
 "Version": "1.2.1",
 "AccessToken": "123456@abc.com"
 }
}

保证配置节点AppSettings存在,剩下的就是以Key-Value的形式来写属性,就可以。

2、外部配置文件

像.Net Framework中一样,可以通过外部配置文件来实现。格式如下

{
 "AppSettings.Url": "D:\\test\\app1.json"
}

采用格式是“配置节点名.外链后缀”的形式。可以设计多级外部配置文件,只要发现有外部配置节点就会向下寻找,并监听链上的所有节点文件的变化。

但是需要注意的是:一旦存在外部配置节点,此文件中的配置节点和参数将不再参与解析

3、可配置初始化参数

包括默认文件路径在内的多个参数均可以修改,详情见代码。

修改后需要手动调用RefreshConfiguration方法,以使配置内容生效,有点像事务处理。建议在项目的Startup方法中修改配置方法。

4、使用

跟.Net Framework中一样,直接调用ConfigurationManager.Appsettings["Title"]就可以了。

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

Net Core全局配置读取管理方法ConfigurationManager

Net Core全局配置读取管理方法ConfigurationManager:最近在学习.Net Core的过程中,发现.Net Framework中常用的ConfigurationManager在Core中竟然被干掉了。 也能理解。Core中使用的配置文件全是Json,不像Framework使用的XML,暂时不支持也是能理解的,但是毕竟全局配置文件这种东西还挺重要的,阅读了一些文章
推荐度:
标签: 方法 net .net
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top