.NET Core採用的全新配置系統[6]: 深入瞭解三種針對文件(JSON、XML與INI)的配置源

来源:http://www.cnblogs.com/artech/archive/2016/08/04/new-config-system-06.html
-Advertisement-
Play Games

物理文件是我們最常用到的原始配置的載體,最佳的配置文件格式主要由三種,它們分別是JSON、XML和INI,對應的配置源類型分別是JsonConfigurationSource、XmlConfigurationSource和IniConfigurationSource。 ...


物理文件是我們最常用到的原始配置的載體,最佳的配置文件格式主要由三種,它們分別是JSON、XML和INI,對應的配置源類型分別是JsonConfigurationSource、XmlConfigurationSource和IniConfigurationSource。 [ 本文已經同步到《ASP.NET Core框架揭秘》之中]

目錄
一、FileConfigurationSource  & FileConfigurationProvider
二、JsonConfigurationSource &JsonConfigurationProvider
三、XmlConfiguationSource & XmlConfiguationProvider
四、IniConfigurationSource & IniConfigurationSource

一、FileConfigurationSource  & FileConfigurationProvider

上述這三個具體的ConfigurationSource類型具有如下一個相同的基類FileConfigurationSource。

   1: public abstract class FileConfigurationSource : IConfigurationSource
   2: {
   3:     public IFileProvider     FileProvider { get; set; }
   4:     public bool              Optional { get; set; }
   5:     public string            Path { get; set; }
   6:     public bool              ReloadOnChange { get; set; }
   7:  
   8:     public abstract IConfigurationProvider Build(IConfigurationBuilder builder);
   9: }

如上面的代碼片段所示,FileConfigurationSource是一個抽象類,它利用一個FileProvider對象來提供原始的配置文件,而Path屬性自然代表配置文件的路徑。Optional屬性表示明當前的FileConfigurationSource是否是可選的配置源,其預設值為False。當某個FileConfigurationSource的Optional屬性為True的時候,如果指定的配置文件路徑不存在,將不會有任何異常被拋出來。由於FileProvider具有監控文件變化的能力,它的ReloadOnChange屬性表示如果被監控的配置文件發生改變後是否需要重新載入配置。

由於FileConfigurationSource總是利用FileProvider來讀取配置文件的內容,所以當我們創建一個具體的FileConfigurationSource對象的時候都需要採用顯式或者隱式的方式指定一個FileProvider對象(關於FileProvider,可以參閱我的“文件系統”博文系列)。我們可以調用擴展方法SetFileProvider將一個預設的FileProvider註冊到ConfigurationBuilder對象上,從相面的代碼片段可以看出註冊的FileProvider被保存到Properties屬性表示的字典對象上,對應的Key為“FileProvider”。

   1: public static class FileConfigurationExtensions
   2: {
   3:     private static string FileProviderKey = "FileProvider";
   4:  
   5:     public static IFileProvider GetFileProvider(this IConfigurationBuilder builder)
   6:     {
   7:         object obj2;       
   8:         if (builder.Properties.TryGetValue(FileProviderKey, out obj2))
   9:         {
  10:             return (builder.Properties[FileProviderKey] as IFileProvider);
  11:         }
  12:         return new PhysicalFileProvider(AppContext.BaseDirectory ?? string.Empty);
  13:     }
  14:  
  15:     public static IConfigurationBuilder SetBasePath(this IConfigurationBuilder builder, string basePath)
  16:     {       
  17:         return builder.SetFileProvider(new PhysicalFileProvider(basePath));
  18:     }
  19:  
  20:     public static IConfigurationBuilder SetFileProvider(this IConfigurationBuilder builder, IFileProvider fileProvider)
  21:     {        
  22:         builder.Properties[FileProviderKey] = fileProvider;
  23:         return builder;
  24:     }
  25: }

通過隱式方式提供的FileProvider通過調用ConfigurationBuilder的另一個擴展方法GetFileProvider方法獲取。從上面給出的代碼片段我們可以看到,它會優先返回我們註冊的FileProvider。如果這樣的FileProvdier尚未註冊,該方法會返回指向當前應用執行目錄的PhysicalFileProvider對象。除了上述這兩個方法,ConfigurationBuilder還具有另一個名為SetBasePath的方法,該方法採用指定的路徑創建一個PhysicalFileProvider對象並對它進行註冊。

雖然JsonConfigurationSource、XmlConfigurationSource和IniConfigurationSource這些針對通過文件類型的ConfigurationSource會提供不同類型的ConfigurationProvider來讀取對應的配置文件並將讀取的內容轉換成一個配置字典,但是這些ConfigurationProvider都派生與如下一個FileConfigurationProvider類型。FileConfigurationSource和FileConfigurationProvider都定義在“Microsoft.Extensions.Configuration
.FileExtensions”這個NuGet包中。

   1: public abstract class FileConfigurationProvider : ConfigurationProvider
   2: {
   3:  
   4:     public FileConfigurationSource Source { get; private set; }
   5:  
   6:     public FileConfigurationProvider(FileConfigurationSource source)
   7:     {
   8:         this.Source = source;
   9:         if (this.Source.ReloadOnChange)
  10:         {
  11:             ChangeToken.OnChange(
  12:                 () => this.Source.FileProvider.Watch(this.Source.Path), 
  13:                 this.Load);
  14:         }
  15:     }
  16:  
  17:     public override void Load()
  18:     {
  19:         IFileInfo fileInfo = this.Source.FileProvider.GetFileInfo(this.Source.Path);
  20:  
  21:         if ((fileInfo == null) || !fileInfo.Exists)
  22:         {
  23:             if (!this.Source.Optional)
  24:             {
  25:                 throw new FileNotFoundException();
  26:             }
  27:             base.Data = new Dictionary<string, string>(
  28:                 StringComparer.OrdinalIgnoreCase);
  29:         }
  30:         else
  31:         {
  32:             using (Stream stream = fileInfo.CreateReadStream())
  33:             {
  34:                 this.Load(stream);
  35:             }
  36:         }
  37:         base.OnReload();
  38:     }
  39:  
  40:     public abstract void Load(Stream stream);
  41: }

我們通過如上所示的代碼片段以簡化的形式模擬了FileConfigurationProvider的實現邏輯。它定義了一個抽象方法Load來完成針對配置文件的讀取和配置字典的生成,該參數代表讀取文件的輸出流。在重寫的Load方法中,它直接利用FileProvider得到描述配置文件的FileInfo對象,並調用此FileInfo對象的CreateReadStream方法得到這個Stream對象。

上面的這個代碼片段還體現了額外一些細節。首先,如果我們將FileConfigurationSource的ReloadOnChange屬性設置為True,意味著我們希望當配置文件發生該表的時候重新載入該文件。FileConfigurationProvider直接利用FileProvider的Watch方法監視配置文件的變換,並將Load方法註冊為回調從而到達配置數據同步的目的。其次,如果指定的配置文件不存在,並且FileConfigurationSource的Optional屬性被設置為True,FileConfigurationProvider是不能拋出FileNotFoundException異常的。

二、JsonConfigurationSource&JsonConfigurationProvider

JsonConfigurationSource代表針對通過JSON文件定義的配置源,該類型定義在NuGet包“Microsoft.Extensions.Configuration.Json”中。如下麵的代碼片段所示,在重寫的Build方法中,如果FileProvider屬性沒有被顯式賦值,它會調用ConfigurationBuilder的擴展方法GetFileProvider得到一個FileProvdier並對該屬性賦值。Build方法最終創建並返回的是一個根據自己創建的JsonConfigurationProvider對象。作為FileConfigurationProvider的繼承者,JsonConfigurationProvider利用重寫的Load方法讀取配置文件的內容並將其轉換成配置字典。

   1: public class JsonConfigurationSource : FileConfigurationSource
   2: {
   3:     public override IConfigurationProvider Build(IConfigurationBuilder builder)
   4:     {
   5:         base.FileProvider = base.FileProvider ?? builder.GetFileProvider();
   6:         return new JsonConfigurationProvider(this);
   7:     }
   8: }
   9:  
  10: public class JsonConfigurationProvider : FileConfigurationProvider
  11: {
  12:     public JsonConfigurationProvider(JsonConfigurationSource source);
  13:     public override void Load(Stream stream);
  14: }

“Microsoft.Extensions.Configuration.Json”這個NuGet包為我們定義瞭如下所示的一系列針對IConfigurationBuilder介面的擴展方法AddJsonFile來完成針對JsonConfigurationSource的註冊。如果調用第一個AddJsonFile方法重載,我們可以利用指定的Action<JsonConfigurationSource>對象對創建的JsonConfigurationSource進行初始化。至於後續的AddJsonFile方法重載,實際上就是通過相應的參數初始化JsonConfigurationSource的Path、Optional和ReloadOnChange屬性罷了。

   1: public static class JsonConfigurationExtensions
   2: {
   3:     public static IConfigurationBuilder AddJsonFile(this IConfigurationBuilder builder, Action<JsonConfigurationSource> configureSource);
   4:     public static IConfigurationBuilder AddJsonFile(this IConfigurationBuilder builder, string path);
   5:     public static IConfigurationBuilder AddJsonFile(this IConfigurationBuilder builder, string path, bool optional);
   6:     public static IConfigurationBuilder AddJsonFile(this IConfigurationBuilder builder, string path, bool optional,bool reloadOnChange);
   7: }

當使用JSON文件來定義配置的時候,我們會發現不論對於何種數據結構(複雜對象、集合、數組和字典),我們都能通過JSON格式以一種簡單而自然的方式來定義它們。同樣以前面定義的Profile類型為例,我們可以利用如下所示的三個JSON文件分別定義一個完整的Profile對象、一個Profile對象的集合以及一個Key和Value類型分別為字元串和Profile的字典。

Profile類型

   1: public class Profile
   2: {
   3:     public Gender          Gender { get; set; }
   4:     public int             Age { get; set; }
   5:     public ContactInfo     ContactInfo { get; set; }
   6: }
   7:  
   8: public class ContactInfo
   9: {
	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...