Net Core 的配置模式以及熱重載配置 Net Core 的配置模式以及熱重載配置

Net Core 的配置模式以及熱重載配置

1. 前言

在提倡微服務及 Serverless 愈來愈普及的當下,傳統 .Net 應用的配置模式每每依賴於一個名爲 web.config 的 XML 文件,在可擴展性和可讀性與時代脫節了。固然,我不會慫恿一會兒把全部應用遷移到 .Net Core 上,本文將在儘可能不引入 .Net Core 開發模式的前提下,得到最大的利益。javascript

在開始以前,咱們仍是先說說 .Net Core 的配置模式有何優點以及最少的依賴。css

1.1 .Net Core 配置模式的優點

  • 支持多種格式,如 Json、ini、Yaml、系統環境變量等
  • 再也不依賴於 web.config ,可同時使用多種配置格式
  • 支持熱重載配置,修改配置能夠不用重啓應用

1.2 最少依賴

nuget install Microsoft.Extensions.Configuration nuget install Microsoft.Extensions.Configuration.Binder nuget install Castle.Windsor (其餘 IOC 框架都可)

若是你安裝的是最新的包,可能會遇到 Microsoft.Extensions.Configuration 系列 Nuget 包沒法安裝的問題,這主要取決當前應用的 .Net 版本,請參考下圖,安裝對應的版本(目前不支持 .Net 4.5 如下的應用)。
版本兼容狀況html

因爲本人喜歡可讀性高的 Json 文件,因此還安裝 Microsoft.Extensions.Configuration.Json 的 Nuget 包。java

2. 示例教程

本文在 Abp 2.1.3 的基礎上實現 .Net Core 的配置模式以及熱重載配置,更詳細的過程可參照我在 Github 上的 提交歷史 。git

2.1 加載配置

.Net Core 配置模式的核心是一個名爲 IConfigurationRoot 的接口對象,須要在應用入口中加載各類配置格式後建立一個 IConfigurationRoot 的實例,在傳統的 .Net Web 應用中是在 Global.asax.cs 中賦值。github

// ConfigurationExtenion.AppConfiguration 爲一個靜態的 IConfigurationRoot 實例。 ConfigurationExtenion.AppConfiguration = new ConfigurationBuilder() .AddJsonFile("appsetting.json", optional: false, reloadOnChange: true) .AddJsonFile("appsetting01.json", optional: true, reloadOnChange: false) .Build();

簡單地解釋一下,咱們須要(在根目錄中) 有一個名爲 "appsetting.json" 的 Json 文件,被修改的同時會重載 ConfigurationExtenion.AppConfiguration 。與之相反的 "appsetting01.json" 則容許不存在,即便存在,被修改時不會重載配置。web

2.2 讀取配置節點

加載配置後,咱們須要把配置讀取出來,在 IConfigurationRoot 中全部配置的信息都是存在於一個個節點中,咱們能夠根據節點名稱來獲取對應的類型對象。redis

/// <summary> /// 獲取節點配置 /// </summary> /// <typeparam name="TService"></typeparam> /// <param name="config"></param> /// <param name="sectionName"></param> /// <returns></returns> internal static TService GetSectionObject<TService>(IConfigurationRoot config, String sectionName) { var section = config.GetSection(sectionName); if (section == null) { throw new ArgumentException($" {sectionName} 未綁定,沒法獲取到配置節點信息!"); } return section.Get<TService>(); }

假設咱們有一個這樣的 "appsetting.json" 文件:mongodb

{
    "RedisConfiguration": { "InstanceDbId": 14, "InstanceRedisConnectionString": "127.0.0.1" }, "MongoDbConfiguration": { "ConnectionString": "mongodb://127.0.0.1:27017/?connectTimeoutMS=300000", "DatatabaseName": "local" } }

若是咱們要獲取 MongoDbConfiguration 下的 ConnectionString 的值,那麼咱們能夠這樣獲取:json

var connectionString= GetSectionObject<String>(ConfigurationExtenion.AppConfiguration,"MongoDbConfiguration:ConnectionString");

2.3 設計配置類

在傳統的 .Net 應用程序中,咱們每每會使用一個靜態變量去存放配置信息。而在有 IOC 的狀況下,更好的方法是設計一個類來存放配置,如上面的 Json 文件咱們能夠設計以下兩個類(在 Visual Studio 選擇性黏貼 Json 會自動生成對象):

public class RedisConfiguration { public int InstanceDbId { get; set; } public string InstanceRedisConnectionString { get; set; } } public class MongodbConfiguration { public string ConnectionString { get; set; } public string DatatabaseName { get; set; } }

2.4 註冊配置

爲了實現熱重載配置,而不是一層不變的值,咱們在 IOC 中獲取配置類時,須要使用工廠方法獲取。在 Windsor 中能夠這麼作:

/// <summary> /// 註冊方法 /// </summary> /// <typeparam name="TService"></typeparam> /// <param name="ioc"></param> /// <param name="factoryMethod"></param> private static void Register<TService>(IIocManager ioc, Func<TService> factoryMethod) where TService : class { ioc.IocContainer .Register( Component.For<TService>() .UsingFactoryMethod(factoryMethod) .LifestyleTransient() //這裏的生命週期是瞬時的,單例不能夠嗎? ); }

結合前面的獲取配置節點,咱們能夠把兩個靜態方法組合起來創造一個新的靜態方法,更方便咱們使用。

/// <summary> /// 註冊配置 /// </summary> /// <typeparam name="TService"></typeparam> /// <param name="ioc"></param> /// <param name="config"></param> /// <param name="sectionName"></param> internal static void InitConfigService<TService>(IIocManager ioc, IConfigurationRoot config, String sectionName) where TService : class { Register(ioc, () => { var service = GetSectionObject<TService>(config, sectionName); return service; }); }

對於前面兩個配置類,咱們能夠這樣注入:

ConfigurationExtenion.InitConfigService<RedisConfiguration>(IocManager,ConfigurationExtenion.AppConfiguration, "RedisConfiguration"); ConfigurationExtenion.InitConfigService<MongodbConfiguration>(IocManager, ConfigurationExtenion.AppConfiguration, "MongoDbConfiguration");

2.5 獲取配置

我在這裏新增一個控制器方法獲取 RedisConfiguration 對象,該方法使用屬性注入獲取指定的配置類,並返回給頁面。

public String GetRedisConfig() { var redisConfig = IocManager.Instance.Resolve<RedisConfiguration>(); return redisConfig.ToJsonString(); }

能夠看到頁面顯示的與 Json 文件中結構一模一:
結果

2.6 熱重載配置

與 .Net Core 不同,在 .Net 4.X 的 Web 應用中只是稍微修改下 Json 文件都會讓整個應用重啓(修改 web.config 一樣會重啓),因此我將 "appsetting.json" 重命名爲 "appsetting.conf" ,在運行時修改某些值,並從新訪問控制器,能夠看到對應的值變了。

效果

須要注意 IIS 的安全配置,Json 或者 ini 也許能直接經過 HTTP 獲取!

3. 結語

經過簡單的使用 .Net Core 配置模式,咱們能夠感覺到其強大魅力,若是你對 .Net Core 更多的瞭解,以及感覺二者的對比,能夠對照我以前寫過的一篇文章。對於熱重載配置,.Net Core 中更可能是使使用IOptionsSnapshot,而爲了儘可能少地引入 .Net Core 的特性,在這裏只是簡單地用了 IOC 的特性。固然,在不使用任何 IOC 的狀況下(若是你懼怕引入 IOC ),定義一個 IConfigurationRoot 的全局靜態實例,也不失爲一個折中的方案。

相關文章
相關標籤/搜索