跟我一起学.NetCore之配置变更监听
前言
通常程序中配置少不了,配置的修改也避免不了,配置的热更新为此给应用程序带来很大的便捷,不用重启,提高用户体验;但往往有时候需要对修改进行审计,也就是需要记录,有时候也会针对配置修改的时候触发相关操作,比如说发邮件通知,或是其他业务操作等,遇到这种情况,配置变更监听的用处就体现出来了,接下来就尝尝鲜去;
正文
在看前两篇文档的小伙伴可能会看到IConfiguration、IConfigurationProvider接口中有一个GetReloadToken()方法,之前只是注释了一下,其实此方法返回的值就是变更通知的核心,如下图的定义:

看看返回的IChangeToken里定义了什么

对于上面GetReloadToken其实最后返回的真正类型是ConfigurationReloadToken,继承与IChangeToken,其作用就是为了通知程序:改变之后的配置源数据已经通过对应的IConfigurationProvider重新加载;看看其中是本质是啥?

通过以上代码显示,其实ConfigurationReloadToken就是利用CancellationTokenSource在OnReload触发的时候进行通知,这里暂且不深入再研究CancellationTokenSource了,不然感觉要跑题了(可以私下研究研究),停,赶紧回来;
大概了解到变更通知的原理,再来回顾一下配置IConfigurationRoot和IConfigurationSection,其实这两个微软其实已经实现了两个类,ConfigurationRoot和ConfigurationSection,有默认的实现,简单看看是如何实现的,稍微进行了重点注释哦;
namespace Microsoft.Extensions.Configuration
{
// 实现了IConfiguration 和ConfigurationRoot
public class ConfigurationRoot : IConfigurationRoot, IConfiguration, IDisposable
{
// 用于存放注册进来的IConfigurationProvider,Provider的作用还记得吗?
private readonly IList<IConfigurationProvider> _providers;
// 默认创建一个ConfirationReloadToken,
private ConfigurationReloadToken _changeToken = new ConfigurationReloadToken();
// 提供一个_providers的访问属性
public IEnumerable<IConfigurationProvider> Providers => _providers;
// 实现中括号访问,获取配置值,看过前两篇文章的应该知道都是用中括号的方式获取值
public string this[string key]
{
get
{ // 注意,这里倒序遍历,这样就会导致相同Key,后注册的配置源会覆盖之前的
for (int num = _providers.Count - 1; num >= 0; num--)
{
if (_providers[num].TryGet(key, out string value))
{
return value;
}
}
return null;
}
set
{
if (!_providers.Any())
{
throw new InvalidOperationException(Resources.Error_NoSources);
}
// 其实这里的设置值只是在内存里,没有持久化
foreach (IConfigurationProvider provider in _providers)
{
provider.Set(key, value);
}
}
}
// 构造函数
public ConfigurationRoot(IList<IConfigurationProvider> providers)
{
if (providers == null)
{
throw new ArgumentNullException("providers");
}
_providers = providers;
_changeTokenRegistrations = new List<IDisposable>(providers.Count);
// 遍历所有有providers,加载数据
foreach (IConfigurationProvider p in providers)
{
// 加载数据
p.Load();
// 注册监听及回调
_changeTokenRegistrations.Add(ChangeToken.OnChange((Func<IChangeToken>)(() => p.GetReloadToken()), (Action)delegate
{
// 通知
RaiseChanged();
}));
}
}
// 获取通知Token
public IChangeToken GetReloadToken()
{
return _changeToken;
}
// 重新加载数据
public void Reload()
{
// 遍历所有provider进行重新加载数据
foreach (IConfigurationProvider provider in _providers)
{
provider.Load();
}
// 发送通知
RaiseChanged();
}
// 触发通知
private void RaiseChanged()
{
Interlocked.Exchange(ref _changeToken, new ConfigurationReloadToken()).OnReload();
}
........省去一些方法......
}
}
ConfigurationSection就不贴代码,其实内部大多都是通过调用了IConfigrationRoot对象的方法来实现的,还是贴个图吧,如下:

由ConfigurationRoot可见,触发通知的方法RaiseChanged在ConfigurationRoot构造函数中(ConfigurationProvider对应的IChangeToken回调中调用)及Reload的方法中进行调用,也就是说当IConfigurationProvider捕捉到配置源改变时会利用IChangeToken进行通知,或通过调用Reload方法加载时也会通知;
好了好了,理论就暂且说这么多了,撸撸代码,看看是如何监听的,话说在前头,理论一大堆,使用很简单,哈哈哈哈哈,控制台程序走起来:

运行结果

经过上面案例演示,一个IChangeToken只能通知一次,需要多次创建,如果多次都是自己肯定很麻烦,所以微软已经想到了,提供了一个静态函数,如下代码优化即可:

运行结果:

静态方法这种形式,就是ConfigurationRoot构造函数中IChangeToken监听的方式,忘了的话往上再看看;
总结
有没有被这节给忽悠了,一个这么简单的使用,还说那么多"废话",写文字不累吗? 我去,又过12点了,洗洗睡觉!!!!!;下次开始说说“Option”~~~
----------------------------------------------
一个被程序搞丑的帅小伙,关注"Code综艺圈",跟我一起学~~~

跟我一起学.NetCore之配置变更监听的更多相关文章
- 配置静态监听解决ORA-12514错误的案例(转)
今天做Linux下DG配置的时候,遇到一个现象,tnsname.ora文件配置都正常,tnsping也正常,监听也正常,但是仍然报ORA-12514错误: SQL> set lin 130 ...
- Tomcat介绍、安装jdk、安装Tomcat、配置Tomcat监听80端口
1.Tomcat介绍 2.安装jdk下载:wget -c http://download.oracle.com/otn-pub/java/jdk/10.0.1+10/fb4372174a714e6b8 ...
- 配置Tomcat监听80端口 配置Tomcat虚拟主机 Tomcat日志
配置Tomcat监听80端口 • vim /usr/local/tomcat/conf/server.xml Connector port=" protocol="HTTP/1.1 ...
- 配置静态监听解决ORA-12514错误的案例
今天做Linux下DG配置的时候,遇到一个现象.tnsname.ora文件配置都正常,tnsping也正常,监听也正常.可是仍然报ORA-12514错误: SQL> set lin 130 pa ...
- 配置Tomcat监听80端口、配置Tomcat虚拟主机、Tomcat日志
6月27日任务 16.4 配置Tomcat监听80端口16.5/16.6/16.7 配置Tomcat虚拟主机16.8 Tomcat日志扩展邱李的tomcat文档 https://www.linuser ...
- CentOS7 配置 SSH监听多个端口方法
一.修改ssh默认端口,防止暴力破解,让系统安全多一点点: i. 在配置文件/etc/ssh/sshd_config文件中修改 Port #AddressFamily any #ListenAddre ...
- 作业调度框架Quartz.NET-现学现用-02-任务监听
原文:作业调度框架Quartz.NET-现学现用-02-任务监听 前言 任务调度系统并不是完美的,它会出现任务执行失败的情况.如果你需要处理任务失败后的逻辑,希望这篇笔记可以为你提供些帮助. Quar ...
- 作业调度框架Quartz.NET-现学现用-02-任务监听 - 简书
原文:作业调度框架Quartz.NET-现学现用-02-任务监听 - 简书 前言 任务调度系统并不是完美的,它会出现任务执行失败的情况.如果你需要处理任务失败后的逻辑,希望这篇笔记可以为你提供些帮助. ...
- Linux centosVMware 配置Tomcat监听80端口、配置Tomcat虚拟主机、Tomcat日志
一.配置Tomcat监听80端口 关闭tomcat报错 [root@davery src]# /usr/local/tomcat/bin/shutdown.sh 重装tomcat即可 vim /usr ...
随机推荐
- DJANGO-天天生鲜项目从0到1-005-FastDFS与Nginx打造自定义文件存储系统
本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...
- asp.net core 3 使用nlog日志组件,使用$ {basedir}保存位置不对,记录下怎么解决
$ {basedir}指向的是 AppDomain.CurrentDomain.BaseDirectory, Asp.Net.Core的解决方法可能如下(在Program.cs中添加两行): var ...
- expect使用技巧
1) 获取命令行参数,例如通过./abc.exp a1 a2执行expect脚本 set 变量名1 [lindex $argv 0] 获取第1个参数a1 set 变量名2 [lindex $argv ...
- state实例
States是SaltStack中的配置语言,在日常进行配置管理时需要编写大量的States文件. 比如我们需要安装一个包,然后管理一个配置文件,最后保证某个服务正常运行. 这里就需要我们编写一些st ...
- 设置x 轴斜体(每次我都百度,这次单独为它发一个)
plt.xticks(rotation = 45) 2020-06-07
- 6.15 省选模拟赛 老魔杖 博弈论 SG函数
这道题确实没有一个很好的解决办法 唯一的正解可能就是打表找规律 或者 直接猜结论了吧. 尽管如此 在此也给最终结论一个完整的证明. 对于70分 容易发现状态数量不大 可以进行暴力dp求SG函数. 原本 ...
- Ynoi专练
为了练习分块 莫队 bitset黑科技 我会写几道Ynoi 放到这里. bitset 每一位占1bit int 每一位占 4 bitye bool占1 bitye long long 8bitye L ...
- luogu3706 [SDOI2017]硬币游戏
LINK:硬币游戏 对于40分的暴力 构造出AC自动机 列出转移矩阵 暴力高消.右转上一篇文章. 对于100分 我们不难想到这个矩阵过大 且没有用的节点很多我们最后只要n个节点的答案 其他节点的答案可 ...
- React Hook~部分实用钩子
useCompareEffect /** * useCompareEffect * useEffect只是普通的浅比较,这里做了深比较 * useEffect的依赖是否相同,相同不触发 */ impo ...
- Maven知识记录(一)初识Maven私服
Maven知识记录(一)初识Maven私服 什么是maven私服 私服即私有的仓库.maven把存放文件的地方叫做仓库,我们可以理解成我门家中的储物间.而maven把存放文件的具体位置叫做坐标.我们项 ...