P3-2 配置系统
配置系统
配置系统的基本使用
说明
- 1、传统Web.config配置的缺点,之前DI讲到过。
- 2、为了兼容,仍然可以使用Web.config和ConfigurationManager类,但不推荐。
- 3、.NET 中的配置系统支持丰富的配置源,包括文件(json、xml、ini等)、注册表、环境变量、命令行、Azure Key Vault等,还可以配置自定义配置源。可以跟踪配置的改变,可以按照优先级覆盖。
- 4、
通过IConfigurationRoot读取配置
和绑定读取配置
这两种方式都只适合特殊情况(极端情况),一般来说还有另外一个方法更加简洁的去使用 - 5、(*)懂了即可
Json文件配置
- 1、创建一个json文件,文件名随意,比如config.json,设置“如果较新则复制”。参考备注
- 2、NuGet安装Microsoft.Extensions.Configuration和Microsoft.Extensions.Configuration.Json。
- Microsoft.Extensions.Configuration:配置框架基础包
- Install-Package Microsoft.Extensions.Configuration
- Microsoft.Extensions.Configuration.Json:读取Json的包
- Install-Package Microsoft.Extensions.Configuration.Json
- Microsoft.Extensions.Configuration:配置框架基础包
- 3、编写代码,先用简单的方式读取配置。
通过IConfigurationRoot读取配置(*)
1 |
|
绑定读取配置(*)
- 1、可以绑定一个类,自动完成配置的读取。
- 2、NuGet安装:Microsoft.Extensions.Configuration.Binder
- 3、Server server = configRoot.GetSection(“proxy”).Get
()
1 |
|
使用选项方式读取配置
用法
- 1、推荐使用选项方式读取,和DI结合更好,且更好利用“reloadonchange”机制。
- 2、NuGet安装:Microsoft.Extensions.Options、Microsoft.Extensions.Configuration.Binder,当然也需要Microsoft.Extensions.Configuration、Microsoft.Extensions.Configuration.Json。
- 3、读取配置的时候,DI要声明
IOptions<T>
、IOptionsMonitor<T>
、IOptionsSnapshot<T>
等类型。- 三者的区别
IOptions<T>
:在配置改变后,我们不能读到新的值,必须重启程序才可以读到新的值IOptionsMonitor
:在配置改变后,我们能读到新的值IOptionsSnapshot
:也是在配置改变后,我们能读到新的值,- 和
IOptionsMonitor
不同的是,IOptionsSnapshot会在同一个范围内会保持一致性(比如ASP.NET Core一个请求中)
- 和
- 建议用IOptionsSnapshot
演示代码
- 1、在读取配置的地方,用IOptionsSnapshot
注入。不要在构造函数里直接读取IOptionsSnapshot.Value,而是到用到的地方再读取,否则就无法更新变化。 - 2、如下配置
1
2
3
4services.AddOptions()
.Configure<DbSettings>(e => config.GetSection("DB").Bind(e))
.Configure<SmtpSettings>(e => config.GetSection("Smtp").Bind(e));
services.AddTransient<Demo>();//不能用Singleton
从命令行读取配置
- 1、配置框架还支持从命令行参数、环境变量等地方读取。
- 2、NuGet安装Microsoft.Extensions.Configuration.CommandLine。
- 3、configBuilder.AddCommandLine(args)
- 4、参数支持多种格式,比如:server=127.0.0.1、–server=127.0.0.1、–server 127.0.0.1(注意在键值之间加空格)、/server=127.0.0.1、/server 127.0.0.1(注意在键值之间加空格)。格式不能混用。
- 5、调试的时候,VS中简化命令行传参数的方法。
- 命令行
- 2019
- 2022
- 命令行
1 |
|
扁平化配置
- 1、对于环境变量、命令行等简单的键值对结构,如果想要进行复杂结构的配置,需要进行“扁平化处理”。对于配置的名字需要采用“层级配置”。例如:
a:b:c
。对于数字这样配置:a:b:c:0
、a:b:c:1
、a:b:c:2
。 - 2、演示一下。
- 3、这个知识点在自定义配置Provider中还会用到。
从环境变量读取配置
- 1、NuGet安装:Microsoft.Extensions.Configuration.EnvironmentVariables。
- 2、然后configurationBuilder. AddEnvironmentVariables()
- AddEnvironmentVariables() 有无参数和有prefix参数的两个重载版本。
- 无参数版本会把程序相关的所有环境变量都加载进来,由于有可能和系统中已有的环境变量冲突,因此建议用有prefix参数的AddEnvironmentVariables()。
- 读取配置的时候,prefix参数会被忽略。
- 3、VS中调试时,避免修改系统环境变量,直接在VS中设置环境变量的方法。
- 环境变量
- 环境变量
1 |
|
其他配置源
1、还支持ini、xml等格式的配置源,如果想用查询文档即可。
2、还支持在运行时、调试时加载不同的json文件;
3、还内置或者第三方支持中心化配置服务器,比如使用Apollo、Nacos等开源服务器,或者使用Azure、阿里云等的配置服务。具体看文档即可。
案例:开发我们的配置提供程序
- 什么是“自己造轮子”
- 本来有现成的框架可以使用,但你非得自己去创造,还不一定有现成的好用
- 对于一个程序员来讲,一定要有自己造轮子的这个能力
- 价值
- 对行业:就是说在行业里边,一定是有一些人不满足于现有的东西,去创造新的东西
- 如果只会用行业内的框架,越用还越觉得越垃圾,但是还必须用~你怎么办呢
- 对自己
- 可以提高自己。当你可以造轮子了,你这时就是创造者了,而并非只是一个使用者
开发自定义配置提供者的步骤
- 1、开发一个直接或者间接实现IConfigurationProvider接口的类XXXConfigurationProvider,一般继承自ConfigurationProvider。
- 如果是从文件读取,可以继承自
FileConfigurationProvider
。 - 重写Load方法,把“扁平化数据”设置到
Data
属性即可。
- 如果是从文件读取,可以继承自
- 2、再开发一个实现了IConfigurationSource接口的类XXXConfigurationSource。
- 如果是从文件读取,可以继承自
FileConfigurationSource
。 - 在Build方法中返回上面的ConfigurationProvider对象。
- 如果是从文件读取,可以继承自
- 3、然后使用即可,configurationBuilder.Add(new ConfigurationSource())即可。
- 为了简化使用,一般提供一个IConfigurationBuilder的扩展方法。
整体流程:编写ConfigurationProvider类实际读取配置;
编写ConfigurationSource在Build中返回ConfigurationProvider对象;
把ConfigurationSource对象加入IConfigurationBuilder。
开发web.config提供者
- 1、.NET Core中不建议使用.NET Framework里的web.config,不过仍然继续提供了ConfigurationManager了,不过没有官方支持通过新的Configuration框架读取的方式。
- 我们来实现一个,能够读取web.config里的connectionStrings和appSettings的内容。没用过web.config也没关系。
- 2、这个项目主要意义还是展示如何编写自定义配置提供者,实用意义不大。主要为下一个更实用的配置提供者做知识准备。
代码写在了“Config1\自定义配置提供”这个项目里
项目需求(开发数据库配置提供者)
- 1、网站用集群部署,如果用本地配置文件,每次修改都要挨个修改。有Apollo、Nacos等开源的配置中心以及云服务平台的配置服务,但是项目对于配置的要求没有非常复杂,因此决定在关系数据库中保存配置。
- 如果项目用不到云服务平台的话,可以用关系数据库中保存配置达到中心化配置的需求
- 2、已经开源 https://github.com/yangzhongke/Zack.AnyDBConfigProvider
- 3、按照文档先使用一下,站在使用者角度体验一下。思考自己如何实现。项目亮点:value支持json格式。
解读源代码
- 1、杨老师github上的源代码。
- 2、重点:定时reload的实现(也可以考虑改成用触发器实时触发);ReaderWriterLockSlim 的使用;json解析为“扁平结构”。
步骤中的问题
- 第一步
- Id的自动增长
- 1.设置主键。 2.设置自动增长
- 在表中写入配置数据
- Id的自动增长
- 第二步
- 在对应的项目中安装第三方包
- Install-Package Zack.AnyDBConfigProvider
- Install-Package Microsoft.Data.SqlClient
- 在对应的项目中安装第三方包
- 第三步
- 在代码中写入配置(下面都是简单写的,具体可以看使用说明中)
1
2
3string conn1 = "Server=127.0.0.1;Database=School;Trusted_Connection=True";
configBuilder.AddDbConfiguration(() => new SqlConnection(conn1), reloadOnChange: true,
reloadInterval: TimeSpan.FromSeconds(2));
- 在代码中写入配置(下面都是简单写的,具体可以看使用说明中)
- 第四步
- 运行
代码写在了“Config1\Config1”这个项目里
多配置源问题
为什么多配置源
- 1、比如:某个网站需要自定义配置;程序员的同一台机器上,开发调试环境和测试环境用不同的配置。
- 2、按照注册到ConfigurationBuilder的顺序,“后来者居上”
- 后注册的优先级高,如果配置名字重复,用后注册的值。
- 如果配置名字不重复,就用前注册的值。后者有则代替,无则保持
- 3、实验:控制台的覆盖环境变量的,自定义Provider的覆盖控制台的。
- 练习
配置文件的重要性
- 把配置文件不小心传到互联网的下场
保命的UserSecrets(为了防止上述事件的发生)
- 1、.NET 提供了user-secrets机制, user-secrets的配置不放到源代码中。
- 2、Nuget安装:Microsoft.Extensions.Configuration.UserSecrets
- 3、在VS项目上点右键【管理用户机密】,编辑这个配置文件。看看这个文件在哪里。会自动在csproj中的UserSecretsId就是文件夹的名字。
- 点击确定后就自动安装了Microsoft.Extensions.Configuration.UserSecrets这个包
- 4、configBuilder.AddUserSecrets
()
注意
- 1、不能泄漏到源码中的配置放到user-secrets即可,不用都放。
- 比如公司的服务器配置文件等
- 2、一般把user-secrets优先级放到普通json文件之前。
- 3、如果开发人员电脑重装系统等原因造成本地的配置文件删除了,就需要重新配置。
- 因为机密文件储存在C盘,所以如果有,记得提前备份
- 4、并不是生产中的加密,只适用于开发环境。
P3-2 配置系统
http://example.com/2024/09/12/Net Core2022教程/第3章:.NET Core核心基础组件/P3-2 配置系统/