文章出處

ConfigurationBuilder在生成以Configuration對象的時候會利用注冊其中的ConfigurationProvider加載原始的配置數據,那么一旦配置源中的數據發生變化,應用程序中的使用的配置信息如何與之同步呢?如果需要在應用程序中實現對配置信息的實施同步,就需要對原始配置數據的進行監控,并在數據改變的時候重新加載配置數據。除此之外,重新加載的配置需要應用到程序中,我們必然需要一種通知機制。

為了讓讀者朋友們對配置同步機制在具體項目中的應用有個感官認識,我們先通過一個簡單的實例來演示如何實現配置數據的實時同步。我們采用一個INI文件作為配置源,通過實施監控這個文件第一時間感知到文件內容的變換。一旦原始配置文件的內容發生改變,應用程序將重新加載配置,并通過注冊的回掉操作應用新的配置。

我們先創建一個ASP.NET Core控制臺應用并在project .json文件中添加相應的依賴。由于對原始配置文件的變換的監控相關的API實現在“Microsoft.Extensions.Configuration.FileProviderExtensions”這個NuGet包中,我們需要按照如下方式添加針對它的依賴。

   1: {
   2:   ...
   3:  
   4:   "dependencies": {
   5:     "Microsoft.Extensions.Configuration.Ini"                       : "1.0.0-rc1-final",
   6:     "Microsoft.Extensions.Configuration.Binder"                    : "1.0.0-rc1-final",
   7:     "Microsoft.Extensions.Configuration.FileProviderExtensions"    : "1.0.0-rc1-final"
   8:   },
   9: }

假設我們需要通過配置來當前應用使用的線程池的容量,這樣的設置需要根據當前的負載進行調整,所以需要很高的時效性,我們希望一旦修改了INI文件的配置,應用程序中針對線程池的相關設置可以立即生效。簡單起見,我們僅僅定義MinThreads 和MaxThreads這兩個分別決定線程池容量區間的配置項,如下所示的ThreadPoolSettings 是對應的Options類型。

   1: public class ThreadPoolSettings
   2: {
   3:     public int MinThreads { get; set; }
   4:     public int MaxThreads { get; set; }
   5:     public override string ToString()
   6:     {
   7:         return string.Format("Thread pool size: [{0}, {1}]", this.MinThreads, this.MaxThreads);
   8:     }
   9: }

我們在作為應用入口的Main方法中編寫了如下一段程序。我們按照我們熟悉的方式將Settinigs .ini 文件作為配置源生成了一個ConfigurationRoot對象,然后將這個INI文件的路徑作為參數調用它的擴展方法ReloadOnChanged方法。顧名思義,當這個ReloadOnChanged方法執行之后,系統會監控指定物理文件的變換并在發生變化后調用ConfigurationRoot的Reload方法重新加載配置。

   1: public class Program
   2: {
   3:     private static IDisposable callbackRegistration;
   4:  
   5:     public static void Main(string[] args)
   6:     {
   7:         IConfigurationRoot configuration = new ConfigurationBuilder()
   8:             .AddIniFile("Settings.ini")
   9:             .Build()
  10:             .ReloadOnChanged("Settings.ini");
  11:  
  12:         callbackRegistration = configuration.GetReloadToken().RegisterChangeCallback(OnSettingChanged, configuration);
  13:  
  14:         Console.Read();
  15:     }
  16:  
  17:     private static void OnSettingChanged(object state)
  18:     {
  19:         callbackRegistration?.Dispose();
  20:         IConfiguration configuration = (IConfiguration)state;
  21:         Console.WriteLine(configuration.Get<ThreadPoolSettings>());
  22:         callbackRegistration = configuration.GetReloadToken().RegisterChangeCallback(OnSettingChanged, state);
  23:     }
  24: }

10ConfigurationRoot的擴展方法 ReloadOnChanged實現了自身承載的配置與原始配置數據的同步,但是如何使用重新加載配置呢?這就要使用到我們在前面一直刻意忽略的一個名為ChangeToken的對象,而IConfiguration接口的GetReloadToken方法返回的就是這么一個對象。如上面的代碼片段所示,我們調用ConfigurationRoot的GetReloadToken方法得到這個ChangeToken對象,并調用ChangeToken的RegisterChangeCallback方法注冊一個在ConfigurationRoot重新加載時會自動執行的回掉操作。

注冊的回掉操作實現在OnSettingsChanged方法中,方法的參數是在調用RegisterChangeCallback方法是指定的ConfigurationRoot對象,我們在該方法中將它承載的配置綁定為ThreadPoolSettings對象并將相關的信息打印在控制臺上。由于ConfigurationRoot每次重新加載的時候都會生成新的ChangeToken,所以我們在OnSettingsChanged方法中重復地調用RegisterChangeCallback方法進行回掉注冊。現在我們直接運行這段程序,然后認為地修改存儲原始配置數據的INI文件。如上圖所示,當每次我們修改這個INI文件的時候,應用程序的配置將實時地與之同步。

 

ASP.NET Core的配置(1):讀取配置信息
ASP.NET Core的配置(2):配置模型詳解
ASP.NET Core的配置(3): 將配置綁定為對象[上篇]
ASP.NET Core的配置(3): 將配置綁定為對象[下篇]
ASP.NET Core的配置(4):多樣性的配置源[上篇]
ASP.NET Core的配置(4):多樣性的配置源[中篇]
ASP.NET Core的配置(4):多樣性的配置源[下篇]
ASP.NET Core的配置(5):配置的同步[上篇]
ASP.NET Core的配置(5):配置的同步[下篇]


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()