赞
踩
在.NET Framework中是将配置信息放在Web.config文件中,修改配置只需要修改配置文件的内容就可。但是当项目变复杂之后,这种简单的配置就显得力不从心。.NET Core中提供了丰富的配置源,包括文件(JSON、XML、INI等)、注册表、环境变量、命令行。Azure Key Vault等,配置系统也支持自定义配置源。
.NET Core读取配置也有很多方式。可以通过IConfigurationRoot读取配置,也可以通过绑定方式把配置读取为一个对象
注意:因为程序在运行的时候默认加载.exe文件同文件夹下的配置文件,而不是项目中的Config.json文件,所以我们需要把Config.json文件设置为生成项目的时候自动复制到生成目录。 如何手动读取配置?
使用选项方式读取配置是.NET Core中推荐的方式,因为他不仅和依赖注入机制结果得更好,而且它可以实现配置修改后自动刷新。
由于使用选项方式读取配置的时候,需要和依赖注入一起使用,因此通常需要创建一个类用于获取注入的选项值。但是接收选项注入的对象的类型不能直接使用DbSettings、SmtpSettings,而要使用IOptions<T>,IOptionsMonitor<T>,IOptionsSnapshot<T>。那么三者有何区别呢?
IOptions<T>:在配置改变后,我们不能读取新的值,必须重启程序。
IOptionsMonitor<T>:配置改变后,可以读到新的值。
IOptionsSnapshot<T>:配置改变后,可以读到新的值,与上者不同的是,上者在同一范围内会保持一致性。
(比如A,B代码都读取同一个配置,在A运行后B运行前更改了配置,使用IOptionsMonitor的话A读取的是旧值,B是新值,使用IOptionsSnapshot的话A,B都是旧值,只有再次进入这个范围才会是新值)
- /*
- * 注入服务到容器
- */
- ConfigurationBuilder configBuilder = new ConfigurationBuilder();
- configBuilder.AddJsonFile("config.json", optional: false, reloadOnChange: true);
- IConfigurationRoot config = configBuilder.Build();
- ServiceCollection services = new ServiceCollection();
- //使用AddOptions方法注册与选项相关的服务
- services.AddOptions()
- .Configure<DbSettings>(e => config.GetSection("DB").Bind(e)) //把DB节点内容绑定到DbSettings模型对象上
- .Configure<SmtpSettings>(e => config.GetSection("Smtp").Bind(e)); //把Smtp节点内容绑定到SmtpSettings模型对象上
- services.AddTransient<Demo>(); //只能注册为瞬态服务,因为在Demo类中用的IOptionsSnapshot<T>生命周期是 "范围"
- using (var sp = services.BuildServiceProvider())
- {
- while (true) //设置无限循环,方便一直反复测试,修改配置文件
- {
- using (var scope = sp.CreateScope()) //因为IOptionsSnapshot<T>会在新范围加载配置,所以每次循环都创建一个范围
- {
- var spScope = scope.ServiceProvider;
- var demo = spScope.GetRequiredService<Demo>();
- demo.Test();
- }
- Console.WriteLine("可以改配置了");
- Console.ReadKey();
- }
- }
-
- class Demo
- {
- private readonly IOptionsSnapshot<DbSettings> optDbSettings;
- private readonly IOptionsSnapshot<SmtpSettings> optSmtpSettings;
- //通过构造方法注入IOptionsSnapshot<DbSettings>和IOptionsSnapshot<SmtpSettings>两个服务
- public Demo(IOptionsSnapshot<DbSettings> optDbSettings,
- IOptionsSnapshot<SmtpSettings> optSmtpSettings)
- {
- this.optDbSettings = optDbSettings;
- this.optSmtpSettings = optSmtpSettings;
- }
- public void Test()
- {
- var db = optDbSettings.Value;//获取具体配置模型对象的值
- Console.WriteLine($"数据库:{db.DbType}, {db.ConnectionString}");
- var smtp = optSmtpSettings.Value;//获取具体配置模型对象的值
- Console.WriteLine($"Smtp:{smtp.Server}, {smtp.UserName}, {smtp.Password}");
- }
- }
-
- //建立两个模型类
- public class DbSettings
- {
- public string DbType { get; set; }
- public string ConnectionString { get; set; }
- }
- public class SmtpSettings
- {
- public string Server { get; set; }
- public string UserName { get; set; }
- public string Password { get; set; }
- }
-
运行结果如下:
此时不要关闭程序,打开程序生成目录下的config.json文件(bin文件夹内),修改文件内容后保存,再点击Enter键,让程序执行下一次循环操作。
可以发现修改了数据库名称,再次运行的时候自动输出了更改后的配置。但是有一个注意点:修改配置文件信息的时候不能直接修改项目中的文件,因为这是源文件,程序运行中下载的是程序生成文件夹(bin文件夹)下的配置文件。
从命令行读取配置特别适合容器化的运行环境
直接运行时为空结果,因为这是命令行读取配置方式。如下找到程序的.exe文件,使用cmd进入命令行后手动输入配置信息即可读出。
Visual Studio中提供了可以设置命令行参数的选项,避免手动打开cmd的麻烦。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。