.NET Core读取配置文件方式详细总结
基于.net core的跨平台开发,配置文件与之前.net framework采用xml的config文件不同,目前主要是采用json文件键值对配置方式读取。
参考网上相关资料总结如下:
一. 引入扩展 system.configuration.configurationmanager
nuget 下载扩展,install-package system.configuration.configurationmanager
使用方式:添加配置文件app.config。读取方式与原.net framework方式一致
优点:兼容.net framework 原有配置方式
缺点:项目运行过程中若需修改app.config文件,对项目中输出的内容没有丝毫影响,debug发现获取到的值的确没有变化,需要重新编译才生效。
二. 引入扩展 microsoft.extensions.options.configurationextensions
nuget 下载扩展,
install-package microsoft.extensions.options.configurationextensions
install-package microsoft.extensions.configuration.fileextensions
install-package microsoft.extensions.configuration.json
使用方式:参考
优点:可以读取application.json中的配置参数,不再使用xml可以说很好的贴近core的设计理念
缺点:运行时修改json文件读取到的内容不会改变,但是至少重启项目可以修改,若要运行时候修改json文件监听实现监听变化。查看源码,可以发现 虽然配置信息是通过addsingleton注入的
但同时也注入了ioptionschangetokensource ,故只需要在获取配置信息时将ioptions<> 替换为 ioptionsmonitor<>(通过监听的option来获取信息),并通过 ioptionsmonitor<>.currentvalue获取即可实时获取到最新的配置信息(存在修改监听)
另外就是,这个方法采用的是反序列化的原理,也就是必须有一个跟配置文件对应的实体类才可以,这个感觉比较鸡肋,放弃。
三. 自定义扩展方法,这个实现自己写,原理是监听文件是否变更,来刷新configuration 配置实现。
参考园友一个实现,具体需要是否有效,要花时间实践一下,,代码如下:
复制代码
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); } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。