配置文件读取
依赖
- microsoft.extensions.configuration
- microsoft.extensions.configuration.abstractions
- microsoft.extensions.configuration.Ini
- microsoft.extensions.configuration.Json
演示以Json文件为例
var builder = new ConfigurationBuilder();
builder.AddJsonFile("appsettings.json"optional:false,reloadOnChange:true);
var configurationRoot = builder.Build();
Console.WriteLine("KEY1:" + configurationRoot["key1"]);
Console.WriteLine("KEY2:" + configurationRoot["key2"]);
Console.WriteLine("KEY3:" + configurationRoot["key3"]);
Console.ReadKey();
AddJsonFile的两个主要参数:optional和reloadOnChange
- optional:当文件不存在时报错
- reloadOnChange:当读取的文件在读取时发生变化能及时获取更新的文件
配置变更的监听
当配置文件发生改变时我们想做出对应的动作,需要用到以下代码实现
var builder = new ConfigurationBuilder();
builder.AddJsonFile("app.json",optional:true,reloadOnChange:true);
var configurationRoot = builder.Build();
IChangeToken token = configurationRoot.GetReloadToken();
ChangeToken.OnChange(() => configurationRoot.GetReloadToken(),() =>
{
Console.WriteLine("KEY1:" + configurationRoot["key1"]);
Console.WriteLine("KEY2:" + configurationRoot["key2"]);
Console.WriteLine("KEY3:" + configurationRoot["key3"]);
});
Console.ReadKey();
ChangeToken.OnChange(func[] , action[]):当配置文件持续不断地变化时,可不间断的去监听配置信息
将配置文件绑定到属性上
依赖
- microsoft.extensions.configuration.Binder
属性类代码
class ConfigTest
{
public string key1 { get; set; }
public bool key5 { get; set; }
public int key6 { get; set; }
}
配置文件
{
"key1": "OrderService.json",
"key5": true,
"key6": 1,
}
实现:
var builder = new ConfigurationBuilder();
builder.AddJsonFile("app.json",optional:true,reloadOnChange:true);
var configurationRoot = builder.Build();
//赋默认值
ConfigTest config = new ConfigTest()
{
key1 = "default",
key5 = false,
key6 = 100,
};
将配置文件和类进行绑定
configurationRoot.Bind(config);
Console.WriteLine("KEY1:" + config.key1);
Console.WriteLine("KEY2:" + config.key5);
Console.WriteLine("KEY3:" + config.key6);
Console.ReadKey();
问题1:当配置文件中出现嵌套时:想获取嵌套中的值(OrderService)
{
"key2": "values2_haha_jaja_真好看",
"key5": true,
"key6": 1,
"OrderService":
{
"key1": "OrderService.json",
"key5": true,
"key6": 101
}
}
只需将上述代码中
configurationRoot.Bind(config);
替换为
configurationRoot.GetSection("OrderService").Bind(config);
即可
问题2:当配置类属性为非public时如何属性注入
将
configurationRoot.Bind(config);
替换为
configurationRoot.Bind(config,
BinderOptions=>
{
//默认为false
BinderOptions.BindNonPublicProperties = true;
});
自定义配置源
步骤
- 实现IConfigurationSource
- 实现IConfigurationProvider
- 实现Add的扩展方法
服务组件集成配置
在Web应用中读取配置
步骤
- 创建***ServiceOptions类用以接收配置文件信息
public class OrderServiceOptions
{
public int MaxOrderCount { get; set; } = 100;
}
- 创建功能类:完成值的查询
public class OrderService : IOrderService
{
IOptions<OrderServiceOptions> _options;
public OrderService(IOptions<OrderServiceOptions> options)
{
this._options = options;
}
public int ShowMaxOrderCount()
{
return _options.Value.MaxOrderCount;
}
}
- 注册
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
//注入
services.Configure<OrderServiceOptions>(Configuration.GetSection("Order"));
services.AddTransient<IOrderService,OrderService>();
.....
}
- 配置文件
{
"Order": {
"MaxOrderCount": 200
}
}
优点:让定义类不在依赖于配置信息,把与配置信息的交互交给Order类去做
问题:再一次访问之后,更改了配置文件,第二次访问时如何获取到更新的配置?
解决方案:
- 如果是以AddSingleton形式注入,在OrderService类中修改以下内容
//改动点 IOptions改为IOptionsMonitor
IOptionsMonitor<OrderServiceOptions> _options;
public OrderService(IOptionsMonitor<OrderServiceOptions> options)
{
this._options = options;
}
public int ShowMaxOrderCount()
{
//Value改为CurrentValue
return _options.CurrentValue.MaxOrderCount;
}
- 如果是以AddSingleton形式注入,在OrderService类中修改以下内容
//改动点 IOptions改为IOptionsSnapshot
IOptionsSnapshot<OrderServiceOptions> _options;
public OrderService(IOptionsSnapshot<OrderServiceOptions> options)
{
this._options = options;
}
public int ShowMaxOrderCount()
{
//Value改为CurrentValue
return _options.Value.MaxOrderCount;
}
- 如果要实现当配置发生变动时进行通知
在OrderService类构造方法中添加
public OrderService(IOptionsMonitor<OrderServiceOptions> options)
{
this._options = options;
//改动在此
_options.OnChange(options =>
{
Console.WriteLine("值发生了改变");
});
}