首页 > 开发 > .Net > 正文

Asp.net core中实现自动更新的Option的方法示例

2019-10-27 12:19:41
字体:
来源:转载
供稿:网友

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可以看到返回内容的变化

本文代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持CuoXin错新网。


注:相关教程知识阅读请移步到ASP.NET教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表