16 | 选项数据热更新:让服务感知配置的变化
选项框架关键类型
- IOptionsMonitor
- IOptionsSnapshot
场景
- 范围作用域类型使用IOptionsSnapshot
- 单例服务使用IOptionsMonitor
通过代码更新选项
- IPostConfigureOptions
示例
延续使用上一节代码,稍微做些特殊处理
将OrderServce服务从Singleton
模式修改为Scope
模式services.AddSingleton<IOrderService, OrderService>() => services.AddScoped<IOrderService, OrderService>()
直接执行程序,输出:
然后我们手动将配置文件MaxOrderCount
的值从10086
修改为10010
,F5刷新页面,发现还是10086
,那我们如何读取到新配置呢?
只需要一点简单的改动
将OrderService
类配置类型从IOptions<OrderServiceOptions>
修改为IOptionsSnapshot<OrderServiceOptions>
using Microsoft.Extensions.Options;
namespace OptionsDemo.Services
{
public interface IOrderService { int ShowMaxOrderCount(); }
public class OrderService : IOrderService
{
private readonly IOptionsSnapshot<OrderServiceOptions> _options;
public OrderService(IOptionsSnapshot<OrderServiceOptions> options)
{
_options = options;
}
public int ShowMaxOrderCount()
{
return _options.Value.MaxOrderCount;
}
}
public class OrderServiceOptions
{
public int MaxOrderCount { get; set; } = 200;
}
}
执行程序,输出:
接着手动将配置文件MaxOrderCount
的值从10086
修改为10010
,F5刷新页面
可以看到已经读到了最新的值:
如果我们的服务是单例模式怎么办呢,我们将注册模式从Scope
为Singleton
,尝试执行会发现启动错误。
这时,我们将IOptionsSnapshot<OrderServiceOptions>
修改为IOptionsMonitor<OrderServiceOptions>
而Monitor``与Snapshot
的定义略微有些不同,它获取值需要去用CurrentValue
字段
using Microsoft.Extensions.Options;
namespace OptionsDemo.Services
{
public interface IOrderService { int ShowMaxOrderCount(); }
public class OrderService : IOrderService
{
private readonly IOptionsMonitor<OrderServiceOptions> _options;
public OrderService(IOptionsMonitor<OrderServiceOptions> options)
{
_options = options;
}
public int ShowMaxOrderCount()
{
return _options.CurrentValue.MaxOrderCount;
}
}
public class OrderServiceOptions
{
public int MaxOrderCount { get; set; } = 200;
}
}
执行输出:,修改之后
我们在单例模式下也可以监控配置的变化,IOptionsMonitor
下有一个方法OnChange
using Microsoft.Extensions.Options;
namespace OptionsDemo.Services
{
public interface IOrderService { int ShowMaxOrderCount(); }
public class OrderService : IOrderService
{
private readonly IOptionsMonitor<OrderServiceOptions> _options;
public OrderService(IOptionsMonitor<OrderServiceOptions> options)
{
_options = options;
_options.OnChange(options =>
{
System.Console.WriteLine($"配置发生变化,新值为 :{options.MaxOrderCount}");
});
}
public int ShowMaxOrderCount()
{
return _options.CurrentValue.MaxOrderCount;
}
}
public class OrderServiceOptions
{
public int MaxOrderCount { get; set; } = 200;
}
}
执行程序之后,手动修改配置文件,输出:
这里输出两次是因为现在是DeBug
模式。
通常情况下,在设计服务的时候,会在ConfigureServices
方法这里添加我们的配置注入,还有服务注入,但当我们服务多起来的时候,会形成大量的代码在这,这里建议使用扩展方法的方式,使我们的代码结构更加良好。
在Services
文件夹添加类OrderServiceExtensions
,将其ConfigureServices
处代码移动到这里
using Microsoft.Extensions.Configuration;
using OptionsDemo.Services;
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;
}
}
}
ConfigureServices
方法处代码修改为
public void ConfigureServices(IServiceCollection services)
{
services.AddOrderService(Configuration.GetSection("OrderService"));
services.AddControllers();
}
如果我们在设计服务的时候还有一些特殊的需求,比如说我们把配置读取出来以后,还需要再内存里面进行一些特殊的处理,我们就可以使用动态配置的方式
动态配置的方式是再我们Configure
的代码之后,调用PostConfigure
的方法
例如,这里我们需要把MaxOrderCount
加1
using Microsoft.Extensions.Configuration;
using OptionsDemo.Services;
namespace Microsoft.Extensions.DependencyInjection
{
public static class OrderServiceExtensions
{
public static IServiceCollection AddOrderService(this IServiceCollection services,IConfiguration configuration)
{
services.Configure<OrderServiceOptions>(configuration);
services.PostConfigure<OrderServiceOptions>(options =>
{
options.MaxOrderCount += 1;
System.Console.WriteLine(options.MaxOrderCount);
});
services.AddSingleton<IOrderService, OrderService>();
return services;
}
}
}
执行输出:
本文作者:hiwwwk
本文链接:https://www.cnblogs.com/wwwk/p/15873384.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步