.NET Core 自定義配置源

正如大家所知,在 .NET Core 中配置文件改成了 appsettings.json舆吮,表面上和 .NET Framework 的 web.configapp.config 好像沒有太大的區(qū)別,只是一種是 json 辱挥,一種是 xml,但其實 .NET Core 的配置體系是一種全新的設(shè)計吻氧,靈活且具擴展性僚匆。這里主要介紹一下在 .NET Core 的配置體系下如何擴展自定義配置源憋飞,配置源其實就是配置信息存放的載體,最常用的就是文件類型争剿。

.NET Core 配置體系

在進行自定義配置源介紹前已艰,我們需要先了解一下 .NET Core 中的配置體系。 .NET Core 的配置體系中主要包含 ConfigurationProvider蚕苇、ConfigurationSource哩掺、ConfigurationBuilderConfiguration 幾大核心對象涩笤。

ConfigurationProvider

實現(xiàn) IConfigurationProvider 接口嚼吞,配置源真正提供者,主要提供配置信息的加載與刷新蹬碧。

ConfigurationSource

實現(xiàn) IConfigurationSource 接口舱禽,提供對應(yīng)的 ConfigurationProvider 具體實例。

ConfigurationBuilder

實現(xiàn) IConfigurationBuilder 接口恩沽,負責(zé)將 ConfigurationSource 添加到配置源集合誊稚,再根據(jù)配置源集合構(gòu)建出 ConfigurationRoot 對象,實現(xiàn) IConfigurationRoot 接口罗心。

Configuration

實現(xiàn) IConfiguration 接口片吊,Configuration 對象在邏輯上體現(xiàn)出樹形化層次結(jié)構(gòu),配置信息均以鍵/值對的方式提供使用协屡。

注 :IConfigurationRootIConfigurationSection 均繼承于 IConfiguration全谤,IConfigurationRoot 表示配置的根節(jié)點肤晓,IConfigurationSection 則表示配置的非根節(jié)點

所以他們之間的關(guān)系就是 ConfigurationProvider 實現(xiàn)配置提供,然后通過 ConfigurationSource 構(gòu)造配置源實例,接著通過 ConfigurationBuilder 將配置源實例 ConfigurationSource 添加到配置源集合中并構(gòu)造出 ConfigurationRoot补憾,最終以 Configuration 對象提供給程序使用漫萄。

relation

默認(rèn)情況下,Configuration 對象的 Providers 屬性包含如下 Provider

providers
  1. ChainedConfigurationProvider:應(yīng)用程序本身相關(guān)配置信息盈匾,如:applicationName腾务、contentRoot;
  2. JsonConfigurationProvider:appsettings.json 和 appsettings.Development.json 中的配置信息削饵;
  3. EnvironmentVariablesConfigurationProvider:環(huán)境變量的配置信息岩瘦;
  4. CommandLineConfigurationProvider:命令行輸入的配置信息;

這些類型的 Provider 在 .NET Core Web 項目中默認(rèn)會自動加載窿撬,不需要手動配置启昧,當(dāng)然預(yù)置的 Provider 并不止這幾種。

自定義配置源

前面提到 .NET Core 的配置體系是具有擴展性的劈伴,所以我們可以實現(xiàn)自定義的配置源密末,比如基于配置中心(如:etcd、apollo跛璧、consul 等)的實現(xiàn)严里,下面將模擬從配置中心獲取,先了解整體實現(xiàn)方式追城,后面也會介紹我們在實際項目中基于 etcd 的實現(xiàn)方案刹碾。

創(chuàng)建 ConfigurationProvider

自定義 Provider 需要繼承 ConfigurationProvider,然后重寫 Load 方法漓柑,設(shè)置 Data 屬性教硫。

public class CustomConfigurationProvider : ConfigurationProvider
{
  public override void Load()
  {
    // 模擬從遠程配置中心獲取配置信息 
    using var httpClient = new HttpClient
    {
      BaseAddress = new Uri("http://localhost:5000")
    };

    var response = httpClient.GetStringAsync("/api/configs")
      .ConfigureAwait(false)
      .GetAwaiter()
      .GetResult();

    if (!string.IsNullOrEmpty(response))
    {
      Data = JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
    }
  }
}

http://localhost:5000/api/configs 接口返回的 json 字符串,如下:

{"name":"beck","company":"mingdao"}

創(chuàng)建 ConfigurationSource

實現(xiàn) IConfigurationSource 接口辆布,在 Build 方法中返回 CustomConfigurationProvider 實例瞬矩。

public class CustomConfigurationSource : IConfigurationSource
{
  public IConfigurationProvider Build(IConfigurationBuilder builder)
  {
    return new CustomConfigurationProvider();
  }
}

加入 ConfigurationBuilder 配置源列表

添加 IConfigurationBuilder 擴展方法 AddCustom,將 CustomConfigurationSource 加入配置源集合中锋玲。

public static class CustomConfigurationExtensions
{
  public static IConfigurationBuilder AddCustom(this IConfigurationBuilder builder)
  {
    return builder.Add(new CustomConfigurationSource());
  }
}

啟動入口添加 AddCustom

Program.cs 中的 ConfigureAppConfiguration 引用自定義配置源:

public static IHostBuilder CreateHostBuilder(string[] args) =>
  Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
      webBuilder.ConfigureAppConfiguration((context, configBuiler) =>
      {
        configBuiler.AddCustom();
      });
      webBuilder.UseStartup<Startup>();
    });

測試效果

再次查看 Configuration 對象的 Providers 屬性景用,發(fā)現(xiàn)已包含 CustomConfigurationProvider

customConfigurationProvider

然后可通過 Configuration 對象獲取對應(yīng) key 的內(nèi)容:

[HttpGet]
public IEnumerable<string> Get()
{
  return new string[] { _configuration["name"], _configuration["company"] };
}
result

總結(jié)

以上完成了一個簡單的自定義配置源,實際情況會比這復(fù)雜些惭蹂。如果關(guān)注過 JsonConfigurationProvider 的配置加載參數(shù)伞插,有一個 reloadOnChange 參數(shù)用來設(shè)置當(dāng)配置文件有變化時是否重新加載,如果 reloadOnChange 設(shè)置為 true盾碗,當(dāng)配置文件變化時不需要重啟服務(wù)就可以生效媚污,很多時候我們是需要 Provider 具有這個功能的,在接下來介紹的 EtcdConfigurationProvider 中會實現(xiàn)廷雅,實現(xiàn)源碼 已在 Github 可供參考耗美。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末京髓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子商架,更是在濱河造成了極大的恐慌堰怨,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛇摸,死亡現(xiàn)場離奇詭異备图,居然都是意外死亡,警方通過查閱死者的電腦和手機赶袄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門揽涮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人弃鸦,你說我怎么就攤上這事绞吁。” “怎么了唬格?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵家破,是天一觀的道長。 經(jīng)常有香客問我购岗,道長汰聋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任喊积,我火速辦了婚禮烹困,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘乾吻。我一直安慰自己髓梅,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布绎签。 她就那樣靜靜地躺著枯饿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诡必。 梳的紋絲不亂的頭發(fā)上奢方,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機與錄音爸舒,去河邊找鬼蟋字。 笑死,一個胖子當(dāng)著我的面吹牛扭勉,可吹牛的內(nèi)容都是我干的鹊奖。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼涂炎,長吁一口氣:“原來是場噩夢啊……” “哼嫉入!你這毒婦竟也來了焰盗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤咒林,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后爷光,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垫竞,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年蛀序,在試婚紗的時候發(fā)現(xiàn)自己被綠了欢瞪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡徐裸,死狀恐怖遣鼓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情重贺,我是刑警寧澤骑祟,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站气笙,受9級特大地震影響次企,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜潜圃,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一缸棵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谭期,春花似錦堵第、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鸳劳,卻和暖如春狰贯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赏廓。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工涵紊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人幔摸。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓摸柄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親既忆。 傳聞我的和親對象是個殘疾皇子驱负,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容