.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,一经查实,立即删除!

相关文章

CF235D-Graph Game【LCA,数学期望】

正题 题目链接:https://www.luogu.com.cn/problem/CF235D 题目大意 给出一棵基环树,每次随机选择一个点让权值加上这个点的连通块大小然后删掉这个点。 求删光所有点时期望权值。 1≤n≤30001\leq n\leq 30001≤n≤3000 解题思路 先找到环,然后考虑暴…

YBTOJ:魔法数字(数位dp)

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

斯特林数

第一类斯特林数 咕咕咕 第二类斯特林数 定义:把 \(n\) 个不同的球放入 \(r\) 个相同的盒子的方案数(盒子不能为空,记为:\(S(n,r)\) 或 \(\begin{Bmatrix}n\\r\end{Bmatrix}\) 。 递推式: \[\begin{Bmatrix}n\\r\end{Bmatrix}\begi…

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,那么它们卷积的结果是…

CF666E-Forensic Examination【广义SAM,线段树合并】

正题 题目链接:https://www.luogu.com.cn/problem/CF666E 解题思路 给出一个串SSS和nnn个串TiT_iTi​。mmm次询问Sa∼bS_{a\sim b}Sa∼b​在Tl∼rT_{l\sim r}Tl∼r​中出现的最多次数并且输出这个串的编号。 1≤∣s∣≤5105,∑Ti≤5104,1≤m≤51051\leq |s|\leq 5\times 10^5…

简简单单组合数学

简简单单组合数学 P3158 [CQOI2011]放棋子 \(\uparrow\) 假组合数学,真 \(\text{DP}\) 。 \(f[i][j][k]\) : 用了 \(i\) 行 \(j\) 列,涂了前 \(k\) 种颜色的方案数。 \(g[i][j][k]\) : 用了 \(i\) 行 \(j\) 列,涂了第 \(k\) 种颜色的方案数(用…

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…

质数与合数

质数与合数 题意: FFF和GGG正在玩一个质数与合数的游戏 一开始有N个石头 FFF和GGG轮流对这堆石头进行操作,FFF每次选择1到K之间的一个数x,并拿走x个石头,拿走之后剩下的石头数量必须是质数 接着GGG进行同样的操作,但…

P6628-[省选联考 2020 B 卷] 丁香之路【欧拉回路,最小生成树】

正题 题目链接:https://www.luogu.com.cn/problem/P6628 题目大意 给出nnn个点的一张完全无向图,i∼ji\sim ji∼j的边权是∣i−j∣|i-j|∣i−j∣。 然后给出mmm条必经边,和起点sss。 求对于每个终点经过所有必经边的最短路径。 1≤n≤2500,0≤m≤n(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()用来对一个元素序列进行…

开机指南

有些博客上了密码&#xff0c;密码是一个 \(100\) 以内的数字(与ACwisher有关) 腾讯QQ PC版 Notepad Div-c 编译选项&#xff1a; -Wl,--stack1024000000 -Wall -lm -O2 -stdc14 // Author:A weak man named EricQian #include<bits/stdc.h> using namespace std; #defin…

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

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

CF5E-Bindian Signalizing【单调栈】

正题 题目链接:https://www.luogu.com.cn/problem/CF5E 题目大意 圆上有nnn个山&#xff0c;两个山之间可以看到当且仅当它们之间的两条弧中有一条满足所有山都不高于它们两个。 求可以看到的山的对数。 3≤n≤106,1≤hi≤1093\leq n\leq 10^6,1\leq h_i\leq 10^93≤n≤106,…