.net core 选项数据热更新:让服务感知配置的变化 电脑版发表于:2020/7/4 17:56 ![.netcore](https://img.tnblog.net/arcimg/hb/c857299a86d84ee7b26d181a31e58234.jpg ".netcore") >#.net core 选项数据热更新:让服务感知配置的变化 [TOC] <br/> 关键类型 ------------ <br/> - IOptionsMonitor<out TOptions> - IOptionsSnapshot<out TOptions> <br/> 场景 ------------ <br/> - 范围作用域类型使用 IOptionsSnapshot - 单例服务使用 IOptionsMonitor 通过代码更新选项 ------------ <br/> - IPostConfigureOptions<TOptions> 内容示例 ------------ >###项目架构 参考:https://www.tnblog.net/hb/article/details/4716 >###通过 Scoped 模式修改 appsetting.json 配置查看结果 <br/> ><font style="color:#2ecc71;font-weight:bold;">Startup.cs</font> ```csharp ... //改成 Scoped模式:每次HTTP请求会创建一个实例 services.AddScoped<IOrderService, OrderService>(); ... ``` >第一次运行结果 ![第一次运行](https://img.tnblog.net/arcimg/hb/e10464b2934648fa9ce11e8e2cd9256e.png) >修改<font style="color:#f1c40f;font-weight:bold;">appsetting.json</font> 把 MaxOrderCount 的值改为 2000 ```json { "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "OrderService": { "MaxOrderCount": 2000 }, "AllowedHosts": "*" } ``` >仍然为200 ![仍然为200](https://img.tnblog.net/arcimg/hb/9fd1b803f419463980540d134c64d5ea.png) >###通过 Scoped模式 以及 Snapshot 进行热更新 ><font style="color:#2ecc71;font-weight:bold;">OrderService.cs</font> ```csharp public class OrderService : IOrderService { IOptionsSnapshot<OrderServiceOptions> _orderServiceOptions; public OrderService(IOptionsSnapshot<OrderServiceOptions> orderServiceOptions) { _orderServiceOptions = orderServiceOptions; } public int ShowMaxOrderCount() { return _orderServiceOptions.Value.MaxOrderCount; } } ``` >同样的操作运行结果 ![同样的操作运行结果](https://img.tnblog.net/arcimg/hb/5d45febd5cf1422db12154d4f819762d.png) >###当通过 单例模式 的时候是怎样的呢? <br/> ><font style="color:#2ecc71;font-weight:bold;">Startup.cs</font> ```csharp ... //改成 单例模式:唯一的一个实例 services.AddSingleton<IOrderService, OrderService>(); ... ``` >我们发现这里直接报错了,无法使用 **IOptionsSnapshot** ![](https://img.tnblog.net/arcimg/hb/8caff8f006dc46f88f5c22fa12182ffd.png) >###通过 单例模式 与 IOptionsMonitor 也可以做到热更新 <br/> ><font style="color:#2ecc71;font-weight:bold;">OrderService.cs</font> ```csharp public class OrderService : IOrderService { IOptionsMonitor<OrderServiceOptions> _orderServiceOptions; public OrderService(IOptionsMonitor<OrderServiceOptions> orderServiceOptions) { _orderServiceOptions = orderServiceOptions; } public int ShowMaxOrderCount() { return _orderServiceOptions.CurrentValue.MaxOrderCount; } } ``` >运行结果 ![运行结果](https://img.tnblog.net/arcimg/hb/caac71d10a1d4905957094043bd520e3.png) >###IOptionsMonitor 可以做到变动时事件监听的效果 <br/> ><font style="color:#2ecc71;font-weight:bold;">OrderService.cs</font> ```csharp public class OrderService : IOrderService { IOptionsMonitor<OrderServiceOptions> _orderServiceOptions; public OrderService(IOptionsMonitor<OrderServiceOptions> orderServiceOptions) { _orderServiceOptions = orderServiceOptions; //添加监听 orderServiceOptions.OnChange((a) => { Console.WriteLine($"The value is Change:{a.MaxOrderCount}"); }); } public int ShowMaxOrderCount() { return _orderServiceOptions.CurrentValue.MaxOrderCount; } } ``` >结果 这里修改了一次出现了两次更改是因为它同时监听了当前项目中的 **appsetting.json** 与运行时的 **appsetting.json** ![结果](https://img.tnblog.net/arcimg/hb/e671aaa5740c4ea98027801bb2a51e24.png) >###使用静态扩展 <br/> >当我们运用大量的依赖注入的时候,可以考虑使用静态扩展方法 <br/> ><font style="color:#2ecc71;font-weight:bold;">OrderServiceExtensions.cs</font> ```csharp namespace Microsoft.Extensions.DependencyInjection { public static class OrderServiceExtensions { public static IServiceCollection AddOrderService(this IServiceCollection services,IConfiguration configuration) { services.Configure<OrderServiceOptions>(configuration); services.AddSingleton<IOrderService, OrderService>(); return services; } } } ``` ><font style="color:#2ecc71;font-weight:bold;">Startup.cs</font> ```csharp ... public void ConfigureServices(IServiceCollection services) { services.AddOrderService(Configuration.GetSection("OrderService")); services.AddControllers(); } ``` >###使用动态配置配置对象 <br/> >比如当加载完成时我们还需要给 **MaxOrderCount** + 100 ><font style="color:#2ecc71;font-weight:bold;">OrderServiceExtensions.cs</font> ```csharp namespace Microsoft.Extensions.DependencyInjection { public static class OrderServiceExtensions { public static IServiceCollection AddOrderService(this IServiceCollection services,IConfiguration configuration) { services.Configure<OrderServiceOptions>(configuration); //动态配置 services.PostConfigure<OrderServiceOptions>(option => { option.MaxOrderCount += 100; }); services.AddSingleton<IOrderService, OrderService>(); return services; } } } ``` >当前配置为:200 结果: ![](https://img.tnblog.net/arcimg/hb/afebedd0cb8a469d8eecbbcb8cf89a00.png)