给每个给做了监听哈:
foreach (var source in _sources) { var registration = ChangeToken.OnChange( () => source.GetChangeToken(), (name) => InvokeChanged(name), source.Name); _registrations.Add(registration); }这个IOptionsChangeTokenSource怎么来的呢?是在我们的configure配置方法中:
public static IServiceCollection Configure<TOptions>(this IServiceCollection services, string name, IConfiguration config, Action<BinderOptions> configureBinder) where TOptions : class { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (config == null) { throw new ArgumentNullException(nameof(config)); } services.AddOptions(); services.AddSingleton<IOptionsChangeTokenSource<TOptions>>(new ConfigurationChangeTokenSource<TOptions>(name, config)); return services.AddSingleton<IConfigureOptions<TOptions>>(new NamedConfigureFromConfigurationOptions<TOptions>(name, config, configureBinder)); }看到这一段:services.AddSingleton<IOptionsChangeTokenSource>(new ConfigurationChangeTokenSource(name, config));。
当有修改后,那么会调用:
private void InvokeChanged(string name) { name = name ?? Options.DefaultName; _cache.TryRemove(name); var options = Get(name); if (_onChange != null) { _onChange.Invoke(options, name); } }这里面会移除缓存_cache.TryRemove(name);,然后重新新调用: Get(name);也就会再绑定一次。
这里面有一个值得注意的是,如果有回调,不一定是本身这个服务的配置修改,可能是其他服务的配置修改了,也会被通知,因为这个是文件发生变化就会被通知。
原理如下:
GetSession会返回一个 ConfigurationSection。那么它里面的GetReloadToken是这样的:
public IChangeToken GetReloadToken() => _root.GetReloadToken();这返回了ConfigurationRoot的GetReloadToken。
实验一下:
{ "SelfService": { "name": "zhangsan" }, "SelfService2": { "name" : "good one" } }改成:
{ "SelfService": { "name": "zhangsan" }, "SelfService2": { "name" : "good one1" } }结果:
索引我们可以在服务里面配置增加一个version版本号,如果版本修改了,然后才做相应的操作。
结以上只是个人整理,如有错误,望请指点。
下一节:配置验证。