Asp.net core中实现自动更新的Option的方法示例
程序员文章站
2022-07-04 21:48:28
asp.net core可以监视json、xml等配置文件的变化, 自动刷新内存中的配置内容, 但如果想每隔1秒从zookeeper、consul获取最新的配置信息, 需要...
asp.net core可以监视json、xml等配置文件的变化, 自动刷新内存中的配置内容, 但如果想每隔1秒从zookeeper、consul获取最新的配置信息, 需要自己实现.
阅读了 asp.net core document的custom configuration provider, 得知只需要实现自己的iconfigurationsource和对应configurationprovider即可
在这个示例中, 我建立了一个简单的option, 只包含一个不断变化的计数器变量.
public class refreshableoptions { public int increasementcount { get; set; } }
实现iconfigurationsource和对应configurationprovider, 内部有一个timer模拟从外部获取了最新的数据, 这里为简单起见, 采用硬编码的方式指定了option的路径
public class autorefreshconfigurationsource : iconfigurationsource { public iconfigurationprovider build(iconfigurationbuilder builder) { return new autorefreshconfigurationprovider(); } } public class autorefreshconfigurationprovider : configurationprovider { private int count = 0; private bool ischanged; public autorefreshconfigurationprovider() : base() { timer timer = new timer(timercallback); timer.change(1000, 3000); } public override void load() { var beforedata = data; // 这里采用硬编码指定option的路径 data = new dictionary<string, string>() { { "autorefreshoptions:increasementcount", count.tostring() } }; ischanged = isdictionarychanged(beforedata, data); } private void timercallback(object state) { count++; this.load(); if (ischanged) { base.onreload();//通知iconfiguration实例, 有参数发生了改变 ischanged = false; } } //判断两个idictionary是否有不同的帮助方法 private static bool isdictionarychanged(idictionary<string, string> before, idictionary<string, string> after) { if (before == null && after == null) { return false; } if ((before == null) != (after == null)) { return true; } if (before.count != after.count) { return true; } var ignorecasebefore = new dictionary<string, string>(before, stringcomparer.ordinalignorecase); foreach (var afteritemkey in after.keys) { if (!ignorecasebefore.trygetvalue(afteritemkey, out var beforeitemvalue)) { return true; } if (beforeitemvalue != after[afteritemkey]) { return true; } ignorecasebefore.remove(afteritemkey); } if (ignorecasebefore.count > 0) { return true; } return false; } }
实现扩展方法
public static class autorereshconfigurationextensions { public static iconfigurationbuilder addautorereshconfiguration(this iconfigurationbuilder builder) { return builder.add(new autorefreshconfigurationsource()); } }
使用方法
新建一个webapi项目, 在program.createwebhostbuilder中增加黄色部分
webhost.createdefaultbuilder(args) .configureappconfiguration(config => { config.addautorereshconfiguration(); }) .usestartup<startup>();
在startup. configureservices中配置
services.configure<refreshableoptions>(configuration.getsection("autorefreshoptions"));
修改valuescontroller
[route("api/[controller]")] [apicontroller] public class valuescontroller : controllerbase { private refreshableoptions refreshableoptions; public valuescontroller(ioptionssnapshot<refreshableoptions> refreshableoptions) { this.refreshableoptions = refreshableoptions.value; } [httpget] public actionresult<ienumerable<string>> get() { return new string[] { "value1", "value2", refreshableoptions.increasementcount.tostring() }; } }
启动后不停的刷新http://localhost:5000/api/values可以看到返回内容的变化
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。