Asp.net core 学习笔记 ( Configuration 配置 )
更新: 2021-03-21
修订版: ASP.NET Core – Configuration & Options
更新: 2021-06-20
IOptions在配置更改时无法对应变更选项的值,只能重启应用。IOptionsSnapshot和IOptionsMonitor则具有这种能力。
搞这么多主要是因为生命周期的控制.
IOptions 的生命周期是跟 application 跑的, 也就是说一旦 application 开始, appsetting 有任何变化都不会影响到 application, 它永远都是拿一开始的值, 直到 app 重启.
sometime 这会是个好的管理方式, 不灵活 = 稳定嘛 但是不灵活也 = 麻烦 (每次修改 appsetting 就一定要重启了)
IOptionsSnapshot 的生命周期是 scope (请求), 也就是说它把声明周期从 app 缩小到每个 request. 灵活一点有时候也不错,不需要动不动就重启 app
需要注意的是 snapshot 的周期是 scope 那么意味着它不能用在单列的 service 哦.
IOptionsMonitor 可以用在单列也可以不需要重启 app, 因为它获取的是 current value. 也就是每一次都拿最新的, 甚至在同一个 request 里面哦. 太过灵活有时候容易出现一些难预料的事儿,这点要特别小心哦.
我目前的想法是尽可能就用 snapshot 然后少用单列 service. (少用的意思是, 如果只是为了性能那就算了呗,用 scope 就好了. 除非真的需要保存一个值在整个 app 周期,那么才用单列)
更新 2020-01-11
IOptions 默认值
var config = ServiceProvider.GetService<IOptions<UploadedFilesPathOptions>>();
即便我们忘了 setup (下图), 我们依然会拿到一个对象(上图), 里面的 value 是 default value
services.Configure<UploadedFilesPathOptions>(Configuration.GetSection("UploadedFilesPath"));
https://blog.wille-zone.de/post/is-ioptions-t-bad/
可能这个行为不是很好理解,因为一般上 DI 如果没有 provide, inject 时是返回 null.
文章说如果你不喜欢可以使用 IOption Factory 改掉这个行为...
更新 : 2019-05-05
name options
services.Configure<SlackApiSettings>("Dev", Configuration.GetSection("SlackApi:DevChannel"));
第一个变量是名字, 然后如下获取
public SlackNotificationService(IOptionsSnapshot<SlackApiSettings> options) { SlackApiSettings devSettings = options.Get("Dev"); }
identity 就是用了这个手法在 CookieAuthenticationOptions 上哦.
更新 : 2019-05-03
set options in startup config
services.Configure<BusinessOptions>(Configuration.GetSection("Email")) // set from appsetting .Configure<BusinessOptions>(options => { add more options.Price = 400; options.Name = "zhu ba jie"; });
参考 : https://cnblogs.com/nianming/p/7083964.html
配置写在 appsettings.json 里头
比如
{ "object": { "prop": "value" }, "array": [ { "prop": "value" } ], "businessConfig": { "paypalEmail" : "hengkeat87@gmail.com" } }
startup.cs
namespace Project { public class BusinessConfig { public string paypalEmail { get; set; } } public class Startup { public Startup(IConfiguration configuration) { this.configuration = configuration; } public IConfiguration configuration { get; } public void ConfigureServices(IServiceCollection services) { // 各种获取 config 的方式 var value = configuration["object:prop"]; value = configuration["array:0:prop"]; var obj = configuration.GetSection("object"); value = obj["prop"]; // 绑定类型 string stringValue = configuration.GetValue<string>("object:prop"); BusinessConfig businessConfig = configuration.GetSection("businessConfig").Get<BusinessConfig>(); // 注册到 service 让 control 可以注入 services.Configure<BusinessConfig>(configuration.GetSection("businessConfig")); } } }
controller.cs
public class HomeController : Controller { private readonly BusinessConfig businessConfig; public HomeController( // IOptionsSnapshot 对比 IOptions 特色是更新 config file 时, snapshot 能获取新值, 很奇怪, 不是说 snapshot 吗 ? 怎么反而可以获取到新值...纳闷 IOptionsSnapshot<BusinessConfig> businessConfigOptionsAccessor, // 能 // IOptions<BusinessConfig> businessConfigOptionsAccessor // 不能 ) { businessConfig = businessConfigOptionsAccessor.Value; } public IActionResult Index() { string paypalEmail = businessConfig.paypalEmail; return View(); } }
Configuration 是可以随时 set 的. 要使用 options 获取 config 就一定要执行 services.Configure.
由于 key-vault 只能放在第一层,所以我们通常需要额外功夫 set 进去.
Configuration["email:password"] = Configuration["key-vault-secret-email-password"]; services.Configure<Email>(Configuration.GetSection("email"));