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

    本文代码

    后记: 这个功能写得比较早, 后来在nuget上发现很多consul configure的扩展, 这段代码就全当练习吧.

  • 相关阅读:
    update 更改字段
    查看 links
    oracle 统计字段空值数
    查看oracle 数据库编码个格式
    oracle 数据库DBA权限
    一文弄懂 Golang 排序
    Golang Linux、Windows、Mac 下交叉编译
    go 简单封装数学运算包
    [Vue warn]: Unknown custom element: did you register the component correctly?
    深度图怎么看行情走势
  • 原文地址:https://www.cnblogs.com/zhouandke/p/10528077.html
Copyright © 2020-2023  润新知