.NET Core 2.x中使用Named Options处理多个强类型配置实例

来源: Using multiple instances of strongly-typed settings with named options in .NET Core 2.x
作者: Andrew Lock
译者: Lamond Lu

640?wx_fmt=jpeg

.NET Core从1.0版本开始,就已经开始使用Options模式绑定强类型配置对象。从那时起到现在,这个特性已经获得了更多的功能。例如在.NET Core 1.1中引入的IOptionsSnapshot类。使用这个类的好处是,当你的配置文件(例如: appsetting.json)发生变化时,它可以帮助我们自动刷新我们的强类型配置对象。

本篇博客中,我们将讨论在依赖注入容器中注册强类型配置的多个实例的几种方式。我将特别说明如何使用Named Options方式来完成注入。

使用强类型配置

Options模式将POCO对象和IConfiguration对象绑定,从而实现强类型配置。因为这一过程我已经在之前一篇博文中介绍过,所以这里我就简述一下。

我们可以将强类型配置对象和配置绑定起来,并注入到你的服务中。

640?wx_fmt=png


你可以在Startup类的ConfigureServices中使用Configure将强类型配置对象和配置中的一个节点绑定起来。

640?wx_fmt=png

以上代码中,Configure方法将你的配置和SlackApiSettings对象绑定了起来。除了以上方式,Configure方法还提供了一个参数为Action的重载,所以你来可以使用如下的方式绑定配置。

640?wx_fmt=png


你可以通过在服务中注入IOptions对象来访问配置好的SlackApiSettings对象。

640?wx_fmt=png

你可以使用IOptions.Value属性,获取到配置好的强类型对象。

除了以上方式,你还可以注入一个IOptionsSnapshot接口对象。

使用IOptionsSnapshot处理配置变化

到目前为止,我所展示的例子都是最典型的用法。但是当我们使用IOption来读取强类型配置时,这意味着你的配置在程序生命周期中是不变的。即配置对象只会计算和绑定一次。假如你在程序运行过程中,更改了appSettings.json文件,程序读取配置时,依然会得到程序启动时的配置对象,而非你修改过之后的配置对象。

对我个人而言,对于大部分场景,使用IOption已经能够解决所有问题。但是如果程序确实需要支持重新加载配置,我们还可以使用ASP.NET Core中的IOptionsSnapshotIOptionsSnapshotIOptions使用方法一样,因此你无需在应用程序中执行任何额外的操作。你只需要使用IOptionsSnapshot.Value属性读取配置对象即可。

640?wx_fmt=png

使用以上方式,如果你在程序启动后,修改了appSettings.json文件,IOptionsSnapshot会在下一次请求时,更新配置值,你就能获取到新的配置值了。这里需要注意的是配置值的生命周期是Scoped, 即在一次请求中,读取到的配置值都是一样的。

注意: 并不是所有的配置提供器都支持配置重新加载。文件类型的配置器都没有问题,但是环境变量配置器就不可以。

重新加载配置在某些情况下可能很有用,但IOptionsSnapshot还有另一个技巧 - 命名选项(Named Options)。 我们很快就会介绍它们,但首先我们将看一下你可能偶尔遇到的问题,您需要拥有多个设置对象实例。

使用一个强类型配置对象的多个实例

IOption的典型用例就是针对细粒度的配置。配置系统让你很容易的为特定服务注入小的,集中的POCO对象。但是如果你需要配置多个具有相同属性的配置对象时,应该怎么做的?例如,为了将消息发送到Slack, 你需要一个Webhook Url和一个DisplayName. 当你调用SendNotification(message)时,SlackNotificationService会使用这些配置来向指定的Slack Channel中发送消息。

如果你想更新SlackNotificationService以允许你向多个频道发送消息,该怎么办?

640?wx_fmt=png

这里我已经为创建了向不同的频道发送消息的方法。但是问题是,我该如何为每个频道配置其对应的Webhook UrlDisplayName

为了提供一些思路,这里我们假设我们的配置文件结构是这样的。

640?wx_fmt=png


为了在SlackNotificationService中读取到响应的配置,这里有3种可行的方案。

1. 创建父类配置对象

第一种方式就是扩展SlackApiSettings类,在其中包含各个频道的配置属性。

640?wx_fmt=png

这里我创建了一个内嵌类ChannelSettings, 并在SlackApiSettings类中添加了针对3个Slack Channel的配置。这个新的配置类,正确反映了appSettings.json文件中的配置结构。

640?wx_fmt=png

SlackNotificationService中,我们还是和之前一样注入的单个配置类对象

640?wx_fmt=png

这种配置方式的优点是易于理解,我们为每个Slack Channel配置了独立的强类型配置。缺点是如果要支持新的Slack Channel, 你每次都需要修改SlackApiSettings类。

2. 为每个Channel配置创建单独的配置类

另外一种方法是我们可以独立配置每个Slack Channel。我们分开配置不同的Slack Channel, 并把他们注入到SlackNotificationService服务中。

例如,我们将ChannelSettings类变成一个抽象类

640?wx_fmt=png

然后每一个Slack Channel的配置类继承ChannelSettings类。

640?wx_fmt=png

为了配置不同的Slack Channel, 我们需要在程序启动时分别绑定不同的配置节点。

640?wx_fmt=png

由于不同的Slack Channel拥有不同的配置,所以我们需要分开将他们注入到SlackNotificationService中。

640?wx_fmt=png

这种方式的好处是当你需要添加新的Slack Channel配置时,你不需要去修改之前定义的配置类结构,你只需要添加一个针对新Slack Channel的配置类。但是它也让事情更加复杂了,你不仅需要为每个新的Slack Channel配置类绑定配置的节点, 还需要修改SlackNotificationService的构造函数添加对新Slack Channel配置类的依赖。

3. 使用Named Options

第三种方案就是本文的主题Named OptionsNamed Options翻译过来就是命名配置,和它的字面意思一样,我们可以使用它为每个强类型配置对象起一个唯一的名称,并在使用时通过指定唯一名称来获取所需的强类型配置对象。

使用Named Options, 你可以拥有同一个强类型配置类的不同实例,并独立配置他们。这意味着,我们可以继续使用本文开头所定义的SlackApiSettings类。

640?wx_fmt=png


我们使用的Configure的2个参数的重载方法,其中第一个参数指定了一个唯一名称,第二个参数指定了配置文件中对应的节点名称。

为了使用这些命名配置(Named Options), 我们需要在SlackNotificationService类的构造函数中注入IOptionSnapshot对象,而不是我们之前使用的IOption对象。IOptionsSnapshot.Get(name)方法允许我们通过传入唯一名称,获取对应的强类型配置对象。

640?wx_fmt=png


这种方式最大的好处是,当添加新的Slack Channel时,你不需要添加任何新的配置类,你只需要针对新的Slack Channel配置一个新的SlackApiSetting对象即可。缺点是从SlackNotificationService的构造函数上,你已经不知道它对应的配置节点是哪个了。

总结

在本篇博客中,我们介绍了如何在ASP.NET Core中使用强类型配置。然后我们讨论了如何在ASP.NET Core的依赖注入容器中添加强类型配置对象的多个实例。这里我们讲解了使用3种不同的方式

  • 创建父类配置对象

  • 为每个Channel配置创建单独的配置类

  • 使用Named Options

原文地址:https://www.cnblogs.com/lwqlun/p/10133041.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318427.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YBTOJ:魔法数字(数位dp)

文章目录题目描述解析题目描述 解析 迷惑。。。 首先,比较容易想到用二进制状态压缩记录1-9是否在十进制中出现过 然后就是整除的问题 如果记录余数,它的模数又有9个 开九维余数直接爆炸。。。 怎么办嘞? 有一个结论: 若&#xf…

Prosjecni(构造)

Prosjecni 【题目摘要】 描述 Slavko很无聊,所以他把正整数填到N*N的方阵中。 如果他填出来的方阵满足以下条件,他会特别高兴: ●每行中的数字的平均值是一个位于同一行的整数。 ●每列中的数字的平均值是一个位于同一列的整数。 ●表中的所…

撒花!中文翻译仓库链接已加入 ML.NET 官方示例网站首页

从2018年12月02日决定开始做ML.NET 示例中文版https://github.com/feiyun0112/machinelearning-samples.zh-cn,然后以每天一篇的速度进行翻译,总共耗时15天,将现有的官方实例全部翻译成了中文,并提交了添加中文链接PR,…

P3803 【模板】多项式乘法(FFT)

P3803 【模板】多项式乘法(FFT) 题目描述 给定一个 n 次多项式 F(x),和一个 m 次多项式 G(x)。 请求出 F(x)和 G(x)的卷积。 从低到高输出F(x)*G(x)的系数 另一种问法: 如果有两个无限序列a和b,那么它们卷积的结果是…

YBTOJ:单词频率(AC自动机)

解析 我对力量一无所知 通过这题,可以看出我对AC自动机还是完全没有理解 qwq 首先容易想到: 建一课trie树,然后建树时记录每个串s的终点,这个点后面每被经过一次,就相当于出现一次该单词s 但是,这种“出现”…

一元一次方程

一元一次方程–逆波兰栈 【题目摘要】 题目描述 SLON是一个调皮的学生,为了让他静下心来,老师给他出了一道数学题: 给定表达式A,A中含有变量x和,-,*,(,)这些符号,括号成对出现,一个算术运算符均对应两个操…

.net core上 K8S(七).netcore程序的服务发现

正文上一章我们分享了k8s的网络代理模式,今天我们来分享一下k8s中的服务发现。1.环境变量模式的服务发现k8s默认为我们提供了通过环境变量来实现服务发现的功能,前提是1.需要service在pod之前创建2.适用于同一命名空间1.1创建servicekubectl create -f n…

ASP.NET Core 实战:使用ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目

一、前言这几年前端的发展速度就像坐上了火箭,各种的框架一个接一个的出现,需要学习的东西越来越多,分工也越来越细,作为一个 .NET Web 程序猿,多了解了解行业的发展,让自己扩展出新的技能树,对…

【CF1199 D,E, F】Welfare State // Matching vs Independent Set // Rectangle Painting 1

2019-08-15下午三道练习题CF1199 思路有点难想 but很好实现 这是原网站链接:传送门 这里只完成D, E, F三题 文章目录D:Welfare State题目大意正解瞅瞅代码E:Matching vs Independent Set题目大意正解代码实现F:Rectangle Painting 1题目大意正解代码实现…

YBTOJ:前缀匹配(AC自动机)

文章目录题目描述解析代码题目描述 解析 做的不错 把trie树真的当成一棵树递归即可 注意一个标记时的问题&#xff1a; void AC(){int lstrlen(s01),pl1;for(int i1;i<l;i){int aask(s0[i]);pltr[pl][a];int kpl;while(k>1){if(ok[k]) break;//注意&#xff01;ok[k]1;…

[HAOI2006]均分数据

[HAOI2006]均分数据 题解&#xff1a; 题目稍微解释一下&#xff1a; 把n个数以分为m组&#xff0c;计算每一组的和&#xff0c;求得到的这m个数的方差。由于分法是任意的&#xff0c;我们要求这些方差中的最小值 我们先用STL中的函数random_shuffle()用来对一个元素序列进行…

Docker最全教程——从理论到实战(八)

在本系列教程中&#xff0c;笔者希望将必要的知识点围绕理论、流程&#xff08;工作流程&#xff09;、方法、实践来进行讲解&#xff0c;而不是单纯的为讲解知识点而进行讲解。也就是说&#xff0c;笔者希望能够让大家将理论、知识、思想和指导应用到工作的实际场景和实践之中…

不定方程(质数与因数)

文章目录题目描述解析代码题目描述 数据范围有误&#xff01;应该是不超过1e6 解析 容易推出&#xff1a; y&#xff08;x∗*∗n!)/(x-n!) 换元&#xff0c;令tx-n&#xff01; 则&#xff1a; yn!(n!)2/t 因为x、y都与t一一对应 所以本题就是求 (n!)2 的因数个数 我们求出n&…

Matlab快速入门

命令行窗口 clc 清屏 clear 清理变量 常用矩阵&#xff1a; x[0:2] 这是转置符号xlinspace(0,2,5) 从0到2分配5个空间xzeros(2,3)两行三列全为0的矩阵、 ones(2)2行2列全为1的方阵 eye(2)单位阵 rand(1,2)产生一行二列的随机数&#xff08;从0到1之间均匀随机数&#xff09;固…

【CF 1191】Tokitsukaze, CSL and Stone Game//Tokitsukaze and Duel//Tokitsukaze and Strange Rectangle

很难想 but很好实现 博弈论专练 传送门 惯例这里只完成D&#xff0c;E&#xff0c;F 话不多说上代码 文章目录D:Tokitsukaze, CSL and Stone Game题目大意题解代码实现E&#xff1a;Tokitsukaze and Duel题目大意题解代码实现E:Tokitsukaze and Strange Rectangle题目大意题解代…

【.NET Core项目实战-统一认证平台】第十一章 授权篇-密码授权模式

上篇文章介绍了基于Ids4客户端授权的原理及如何实现自定义的客户端授权&#xff0c;并配合网关实现了统一的授权异常返回值和权限配置等相关功能&#xff0c;本篇将介绍密码授权模式&#xff0c;从使用场景、源码剖析到具体实现详细讲解密码授权模式的相关应用。.netcore项目实…

YBTOJ:灯光控制(贪心)(公倍数)(暴力枚举)

文章目录题目描述解析代码题目描述 解析 没有想出来 首先可以确定开关要么开一次&#xff0c;要么不动&#xff0c;其他都和这俩是等价的 一开始最先想到的就是贪心的方法&#xff0c;每个开关遍历&#xff0c;如果按下会使答案变好就按下。 但是显然当前的开闭对后面是有后效…

Tree Constructer

题目&#xff1a; 题意&#xff1a; 如果点x和y有连边&#xff0c;当且仅当a[x] or a[y] 260 - 1 &#xff08;两者是充分必要&#xff09; 现在给你边的关系&#xff0c;问你每个点的值应该是多少&#xff1f;&#xff08;给出一种情况即可&#xff09; 题解&#xff1a; …

[USACO19JAN,Platinum]Train Tracking 2

虽然是简单的dp &#xff0c;but真的太难想到了&#xff0c;而且我的码力。。。 Train Tracking 2 【题目描述】 每天特快列车都会经过农场。列车有N节车厢&#xff08;1≤N≤105&#xff09;&#xff0c;每节车厢上有一个1到109之间的正整数编号&#xff1b;不同的车厢可能会…

.netcore 堆栈调用方法小记

1|0背景上午临近午饭时&#xff0c;公司同事反馈验证码被攻击灌水。我们匆忙查询验证码明细&#xff0c;对已频繁出现的IP插入黑名单&#xff0c;但IP仍然隔断时间频繁变动&#xff0c;不得已之下只能先封禁对应公司id的验证码发送功能。年初时候&#xff0c;专门对SSO站点的发…