生活中只有两种选择:重新开始,成为自己生活的主角;或留在原处并成为他人的支持角色。生活中,很多时候都需要我们要耐心,耐心做人,耐心做事,更要耐心生活。
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可以看到返回内容的变化
本文代码
以上就是Asp.net core中实现自动更新的Option的方法示例。心,可以超越困难、突破阻挠;心,可以粉碎障碍;心,最终必会达到你的期望。然而,成功的的障碍,往往又是你的心!是你面对不可能完成的高度时,心为自己设定的瓶颈。更多关于Asp.net core中实现自动更新的Option的方法示例请关注haodaima.com其它相关文章!