勇哥注:
传统的web.config和app.config的缺点是必须存在于本地,并且使用上也不方便。
.NET中为了兼容,仍然可以使用web.config和ConfigurationManager类,但是不推荐。
.NET中的配置系统支持丰富的配置源,包括文件(json,xml,ini等),注册表,环境变量,
命令行,Azure Key Vault(云端配置服务器)等,还可以配置自定义配置源。可以跟踪配置的改变,多个配置文件时可以按照优先级覆盖。
这些变化使用得.NET的配置文件功能更符合现代程序的需求,比如面向云的配置文件的需求。
(一)最经典的是本地json文件方式
1。 创建一个json文件,比如config.json,设置“如果较新则复制”。
2。 NuGet安装Microsoft.Extensions.Configuration和Microsoft.Extensions.Configuration.Json
Microsoft.Extensions.Configuration 是配置框架的包,因为它支持许多种配置方式
Microsoft.Extensions.Configuration.Json是它的一种方式,因此需要装两个包
使用nuget的程序包管理器控制台进行安装:
准备好json文件,内容如下:
{ "Age": "32", "Name": "刘备", "Proxy": {"Address": "wuhan"} }
json文件可以选择WEB下的模板,如下图。
其实你也可以选择一个纯文本文件,改扩展名为json也可以。
注意此json文件属性要选择”如果较新则复制“,否则它不会被复制到bin目录,会引发运行时出错。
(1.1) 基本方式
这一种方式跟我们读app.config或者web.config方式相似。
ConfigurationBuilder cbuilder = new ConfigurationBuilder(); cbuilder.AddJsonFile("myconfig.json", optional: true, reloadOnChange: true); IConfigurationRoot configroot = cbuilder.Build(); var name = configroot["name"]; var add = configroot.GetSection("Proxy:Address").Value; //要读的值是一个对象时 Console.WriteLine($"name={name},Address={add}"); Console.ReadKey();
结果:
name=刘备,address=wuhan
(1.2) 用对象方式读取配置
请先安装下面的包:
Microsoft.Extensions.Configuration.Binder
代码:
static void Main(string[] args) { ConfigurationBuilder cbuilder = new ConfigurationBuilder(); cbuilder.AddJsonFile("myconfig.json", optional: true, reloadOnChange: true); IConfigurationRoot configroot = cbuilder.Build(); MyData? data= configroot.Get<MyData>(); Console.WriteLine($"name={data.Name},Age={data.Age},Address={data.Proxy.address}"); Console.ReadKey(); } public class MyData { public int Age { get; set; } public string? Name { get; set; } public Proxy? proxy { get; set; } } public class Proxy { public string? Address { get; set; } }
结果:
name=刘备,Age=32,Address=wuhan
(三)使用选项方式读取,和DI结合,也更好利用reloadonchange机制。
(推荐)
需要安装 :
Microsoft.Extensions.Options
Microsoft.Extensions.Configuration.Binder
Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.Json
Microsoft.Extensions.DependencyInjection //这个是IoC框架
以使用nuget控制台指令,示例如下:
PM> install-package Microsoft.Extensions.Options
读取配置的时候,DI要声明IOptions<T> IOptionsMonitor<T> IOptionsSnapshot<T>等类型
IOptions<T>不会读取到新的值;和IOptionsMonitor相比,
IOptionsMonitor 会立刻读到新的值
IOptionsSnapshot会在同一个范围内(比如asp.net core一个请求中)保持一致。
建议用IOptionsSnapshot。
1。在读取配置的地方,用IOptionsSnapshot<T>注入。
不要在构造函数里直接读取IOptionsSnapshot.Value, 而是到用到的地方再读取,
否则就无法更新变化。
2。 如下配置
Sservices.AddOptions().Configure<DbSettings>(e=> config.GetSection("DB").Bind(e))
.Configure<SmtpSettings>(e=>config.GetSection("Smtp").Bind(e));
services.AddTransient<Demo>(); //不能用Singleton
json文件内容:
{ "Age": "32", "Name": "刘备", "Proxy": { "Address": "wuhan" } }
源码:
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System.Xml.Linq; namespace ConsoleApp1 { internal class Program { static void Main(string[] args) { ServiceCollection services = new ServiceCollection(); services.AddScoped<ConfigController>(); services.AddScoped<ConfigController2>(); ConfigurationBuilder cbuilder = new ConfigurationBuilder(); cbuilder.AddJsonFile("config.json", optional: true, reloadOnChange: true); IConfigurationRoot configroot = cbuilder.Build(); //让DI把 MyData对象绑定到根结点上去 services.AddOptions() .Configure<MyData>(e => configroot.Bind(e)) .Configure<Proxy>(e => configroot.GetSection("Address").Bind(e)); services.BuildServiceProvider(); using (var sp = services.BuildServiceProvider()) { while (true) { using (var scope = sp.CreateScope()) { var c = scope.ServiceProvider.GetRequiredService<ConfigController>(); c.Test(); var d = scope.ServiceProvider.GetRequiredService<ConfigController2>(); d.Test(); } Console.WriteLine("按任意键继续...."); Console.ReadKey(); } } } } public class MyData { public int Age { get; set; } public string? Name { get; set; } public Proxy? proxy { get; set; } } public class Proxy { public string? Address { get; set; } } }
控制器:
DI还是通过构造函数方法 ,注入IOptionsSnapshot<MyData>
using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp1 { public class ConfigController { public readonly IOptionsSnapshot<MyData> optConfig; public ConfigController(IOptionsSnapshot<MyData> optConfig) { //这里一定要返回IOptionsSnapshot对象,而不是取它的值(就是MyData) //如果取它的value的话,你就失去了灵活性,当配置文件修改时,就得不到更新的内容了。 //this.optConfig = optConfig.Value; this.optConfig = optConfig; } public void Test() { Console.WriteLine(optConfig.Value.Age); Console.WriteLine("********"); Console.WriteLine(optConfig.Value.Age); } } public class ConfigController2 { public readonly IOptionsSnapshot<Proxy> optConfig; public ConfigController2(IOptionsSnapshot<Proxy> optConfig) { this.optConfig = optConfig; } public void Test() { Console.WriteLine(optConfig.Value.Address); } } }
修改一下json文件的Age为22,然后接任意键,可以看到现在值更新了。
源码下载:
链接:https://pan.baidu.com/s/1ssZLHX9mqLVhGeBiVmZ0cg
提取码:2nr9
--来自百度网盘超级会员勇哥V6的分享
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!

