.NET Core开发实战(第16课:选项数据热更新:让服务感知配置的变化)--学习笔记...
16 | 選項數據熱更新:讓服務感知配置的變化
選項框架還有兩個關鍵類型:
1、IOptionsMonitor
2、IOptionsSnapshot
場景:
1、范圍作用域類型使用 IOptinsSnapshot
2、單例服務使用 IOptionsMonitor
通過代碼更新選項:
IPostConfigureOptions
延續上一節的代碼,但是做一些特殊處理,之前注冊 Order 服務用的是單例模式,這里改為 Scoped 模式
public void ConfigureServices(IServiceCollection services) {services.Configure<OrderServiceOptions>(Configuration.GetSection("OrderService"));//services.AddSingleton<IOrderService, OrderService>();services.AddScoped<IOrderService, OrderService>();services.AddControllers(); }service 還是使用 IOptions
public class OrderService : IOrderService {IOptions<OrderServiceOptions> _options;public OrderService(IOptions<OrderServiceOptions> options){_options = options;}public int ShowMaxOrderCount(){return _options.Value.MaxOrderCount;} }啟動程序,輸出如下:
orderService.ShowMaxOrderCount:200修改配置
{"OrderService": {"MaxOrderCount": 2000} }啟動程序,輸出如下:
orderService.ShowMaxOrderCount:200輸出值還是200
那么如何能夠讀到新的配置呢?
只需要把 IOptions 換成 IOptionsSnapshot 即可
IOptionsSnapshot<OrderServiceOptions> _options;public OrderService(IOptionsSnapshot<OrderServiceOptions> options) {... }這是因為我們的服務注冊的是 Scoped 模式,并且使用 Snapshot 來讀取配置,每次請求都會重新計算并讀取配置
那如果我們的服務是單例的時候怎么辦呢?
把服務注冊改為單例模式
services.AddSingleton<IOrderService, OrderService>();這里需要使用另一個接口,把 Snapshot 改為 Monitor
IOptionsMonitor<OrderServiceOptions> _options;public OrderService(IOptionsMonitor<OrderServiceOptions> options) {... }Monitor 與 Snapshot 的定義略微有些不同,它獲取值是需要用 CurrentValue 字段
public int ShowMaxOrderCount() {return _options.CurrentValue.MaxOrderCount; }啟動程序,修改配置文件,刷新瀏覽器,可以看到輸出了修改后的數據,也就是說單例對象同時也能讀取到最新的配置
如果說我想知道配置的值發生變化并且通知到我的 Options 怎么做呢?
首先看一下 Monitor 的定義
namespace Microsoft.Extensions.Options {public interface IOptionsMonitor<out TOptions>{TOptions CurrentValue { get; }TOptions Get(string name);IDisposable OnChange(Action<TOptions, string> listener);} }它有一個 OnChange 方法,也就是說可以監聽它的變更
public OrderService(IOptionsMonitor<OrderServiceOptions> options) {_options = options;_options.OnChange(option =>{Console.WriteLine($"配置更新了,最新的值是:{_options.CurrentValue.MaxOrderCount}");}); }啟動程序,修改配置,可以看到輸出配置變化,也就是說可以在單例模式下監聽到 Options 的變化
通常情況下,在設計服務的時候,會在 ConfigureServices 添加配置注入、服務注入,但是當配置多起來的時候,注入代碼就會非常多
那么如何使代碼結構更加良好?
實際上可以把服務注冊的代碼放在靜態擴展方法里,使得 ConfigureServices 更加簡潔
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;}} }這樣在 Startup 的注冊就變得更為簡單了
services.AddOrderService(Configuration.GetSection("OrderService"));我們在設計系統的時候會涉及大量的 service,所以我們可以把 service 的注冊提煉在擴展方法里,不同的模塊用不同的擴展方法隔開,使模塊之間更加清晰,代碼的結構也更加的清晰
那么實際上我們在設計服務的時候,還有一些特殊的述求,比如說把配置讀取出來之后,還需要在內存里面進行一些特殊的處理,我們就可以使用動態配置的方式
動態配置的方式是在我們的 Configure 的代碼之后,調用 PostConfigure 的方法,這里需要配置 OrderServiceOptions
{public static class OrderServiceExtensions{public static IServiceCollection AddOrderService(this IServiceCollection services,IConfiguration configuration){services.Configure<OrderServiceOptions>(configuration);services.PostConfigure<OrderServiceOptions>(options =>{options.MaxOrderCount += 20;});services.AddSingleton<IOrderService, OrderService>();return services;}} }啟動程序,可以看到輸出動態增加了20
總結
以上是生活随笔為你收集整理的.NET Core开发实战(第16课:选项数据热更新:让服务感知配置的变化)--学习笔记...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HttpClientFactory的套路
- 下一篇: 如何使用有序GUID提升数据库读写性能