net core獲取appsetting.json的另一種思路(全局,實時變化無需重啓項目)

最近在寫net core的項目,在非controller和service裏面須要用到appsetting.json文件裏面的一些配置,查資料大概有幾種思路:數據庫

  • 注入,而後config.GetSection("xxx")
  • 寫一個監聽,filewatch,去監聽appsetting.json的變化,讀取key-value。
  • 工具類裏面傳入再走一遍 new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile($"appsettings.json", optional: true, reloadOnChange: true)
  • 使用IOptions<TOptions>,建立對應的實體類

我在查資料的時候發現了一個IOptionsMonitor<T>,這個能夠監聽到文件的變化,結合IOptionsMonitor<T>,我寫了一個工具類,具體使用辦法以下:json

(1)建立appsetting.json對應的實體類文件,屬性的名字要與配置文件裏面的一一對應。app

 1 public class AllSetting
 2 {
 3         ///// <summary>
 4         ///// 數據庫配置
 5         ///// </summary>
 6         public ConnectionSetting ConnectionStrings { get; set; }
 7 
 8         ///// <summary>
 9         ///// 日誌模塊
10         ///// </summary>
11         public LoggingSetting Logging { get; set; }
12 
13         ///// <summary>
14         ///// AllowedHosts 
15         ///// </summary>
16         public string AllowedHosts { get; set; }
17 }
 1 {
 2     "ConnectionStrings": {
 3         "DefaultConnection": "xxxx"
 4         //"PgSqlConnection": "xxxx",
 5         //"MySqlConnection": "xxxx",
 6         //"OracleConnection": "xxxx"
 7     },
 8     "Logging": {
 9         "LogLevel": {
10             "Default": "Warning"
11         }
12     },
13     "AllowedHosts": "*",
14     "Gateway": {
15         "Uri": "xxxx"
16     }
17 }

(2) 編寫工具類AppsettingsUtilityide

  1  /// <summary>
  2     /// 全局獲取app的設置工具類
  3     /// </summary>
  4     public class AppsettingsUtility
  5     {
  6         /// <summary>
  7         /// log4net
  8         /// </summary>
  9         private readonly ILog log;
 10 
 11         /// <summary>
 12         /// serviceProvider
 13         /// </summary>
 14         private static ServiceProvider serviceProvider;
 15 
 16         /// <summary>
 17         /// _services
 18         /// </summary>
 19         private static IServiceCollection _services;
 20 
 21         /// <summary>
 22         /// _configuration
 23         /// </summary>
 24         private static IConfiguration _configuration;
 25 
 26         /// <summary>
 27         /// 初始化工具類
 28         /// </summary>
 29         /// <param name="provider"></param>
 30         public AppsettingsUtility(IServiceCollection services, IConfiguration configuration)
 31         {
 32             _services = services;
 33             _configuration = configuration;
 34             // 倉庫名 統一的
 35             log = LogManager.GetLogger("倉庫名", typeof(AppsettingsUtility));
 36             if (_services == null || _configuration == null)
 37             {
 38                 log.Error("初始化配置工具類發生異常:_services或_configuration爲空");
 39                 throw new NullReferenceException("初始化配置工具類發生異常");
 40             }
 41             try
 42             {
 43                 serviceProvider = _services.BuildServiceProvider();
 44             }
 45             catch (Exception ex)
 46             {
 47                 log.Error("_services.BuildServiceProvider()失敗:" + ex.ToString());
 48             }
 49         }
 50 
 51         /// <summary>
 52         /// 獲取IOptionsMonitor<T>
 53         /// </summary>
 54         /// <typeparam name="T">泛型</typeparam>
 55         /// <returns>IOptionsMonitor<T></returns>
 56         public static IOptionsMonitor<T> GetMonitor<T>()
 57         {
 58             if (serviceProvider == null)
 59             {
 60                 throw new NullReferenceException("獲取失敗,ServiceProvider爲空");
 61             }
 62             if (typeof(T) != typeof(AllSetting))
 63             {
 64                 // TODO: 要限定傳遞的參數值或者每一個setting都註冊一遍
 65             }
 66             return serviceProvider.GetRequiredService<IOptionsMonitor<T>>();
 67         }
 68 
 69         /// <summary>
 70         /// 獲取單個的設置實體
 71         /// </summary>
 72         /// <typeparam name="T">泛型</typeparam>
 73         /// <returns>T</returns>
 74         public static T GetSettingsModel<T>()
 75         {
 76             if (serviceProvider == null)
 77             {
 78                 throw new NullReferenceException("獲取失敗,ServiceProvider爲空");
 79             }
 80             if (typeof(T) != typeof(AllSetting))
 81             {
 82                 // TODO: 要限定傳遞的參數值或者每一個setting都註冊一遍
 83             }
 84             return serviceProvider.GetRequiredService<IOptionsMonitor<T>>().CurrentValue;
 85         }
 86 
 87         /// <summary>
 88         /// 經過key獲取設置
 89         /// </summary>
 91         /// <param name="key">key</param>
 92         /// <returns>設置內容</returns>
 93         public static string GetSetting(string key)
 94         {
 95             if (_configuration == null)
 96             {
 97                 throw new NullReferenceException("獲取失敗,IConfiguration爲空");
 98             }
 99             if (string.IsNullOrEmpty(key))
100             {
101                 throw new NullReferenceException("獲取失敗,key不能爲空");
102             }
103             return _configuration.GetSection(key).Value;
104         }
105     }

(3)在Startup中註冊工具

1  // 注入設置類到管道中
2 services.AddOptions();
3 services.Configure<AllSetting>(Configuration);
4 // 初始化工具類
5 new AppsettingsUtility(services,Configuration);

(4)使用性能

1 var aa = AppsettingsUtility.GetMonitor<AllSetting>().CurrentValue;
2 var bb = AppsettingsUtility.GetSettingsModel<JwtSetting>();
3 var bb = AppsettingsUtility.GetSetting("Appsetting:xxx");

 

若是把配置文件改變了,再調用獲取設置的時候,設置的值會更新,項目不用重啓。這樣作對性能的影響沒有測試。測試

若是我這邊的思路有什麼錯誤的話,還望批評指出。ui

相關文章
相關標籤/搜索