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

     更新时间:2019年03月14日 10:09:32   作者:zhouandke   我要评论

    这篇文章主要介绍了Asp.net core中实现自动更新的Option的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

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

    本文代码

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

    您可能感兴趣的文章:

    相关文章

    最新评论

    山东群英会开奖查询