.NET?Core中配置Configuration的學習指南
什么是配置
.NET中的配置,本質(zhì)上就是key-value鍵值對,并且key和value都是字符串類型。
在.NET中提供了多種配置提供程序來對不同的配置進行讀取、寫入、重載等操作,這里我們以為.NET 的源碼項目為例,來看下.NET中的配置主要是有那些類庫。下面這個截圖是.NET 源碼中和配置相關(guān)的所有類庫,所有配置相關(guān)的類庫都是都是以Microsoft.Extensions.Configuration開頭的。
貌似很多,沒關(guān)系我們來簡單理解一下。
類庫名稱 | 類庫作用 |
---|---|
1、Microsoft.Extensions.Configuration.Abstractions | 定義配置相關(guān)的接口,其他所有配置類庫都必須引用這個類庫 |
2、Microsoft.Extensions.Configuration | Microsoft.Extensions.Configuration.Abstractions類庫的簡單實現(xiàn) |
3、配置提供程序:Microsoft.Extensions.Configuration.CommandLine | 基于命令行的配置提供程序,負責對命令行的配置進行讀寫、載入、重載等操作。 |
4、配置提供程序:Microsoft.Extensions.Configuration.EnvironmentVariables | 基于環(huán)境變量的配置提供程序,負責對環(huán)境變量的配置進行讀寫、載入、重載等操作 |
5、配置提供程序:Microsoft.Extensions.Configuration.FileExtensions | 基于的文件提供程序的基類庫,文件提供程序包括基于Json文件、Ini文件、Xml文件或者自定義文件等。 |
6、配置提供程序:Microsoft.Extensions.Configuration.Json | 基于Json文件的配置提供程序程序,負責從Json文本文件中對配置讀寫、載入、重載等操作。 |
7、配置提供程序:Microsoft.Extensions.Configuration.Ini | 基于Ini文件的配置提供程序,負責從Ini文件中對配置進行讀寫、載入、重載等操作。 |
8、配置提供程序:Microsoft.Extensions.Configuration.UserSecrets | 基于UserSecrets的配置提供程序,這個本質(zhì)上也是一種基于Json文件類型的配置程序。主要用于管理應(yīng)用機密 |
9、Microsoft.Extensions.Configuration.Binder | 負責將key-value鍵值對的配置列表綁定到指定的C#實體類上,方便程序使用。 |
從上面可以看到,主要有四個類庫:第1個類庫Abstractions
負責定義配置的一些接口,第2個類庫Configuration
負責定義配置的簡單實現(xiàn)。第3到第8個類庫都是具體的配置提供程序,第9個類庫Binder
負責將配置綁定到指定的的Model,方便程序使用。
配置提供程序,.NET中有多個類庫提供程序,每個類庫提供程序都是以單獨的類庫向外提供,基本上每個類庫就是三個文件,分別是ConfigurationExtensions.cs、ConfigurationProvider.cs和ConfigurationSource.cs,這三個類分別表示配置的擴展方法、配置提供程序和配置源。配置源用于生成配置提供程序。
在第2個類庫中,微軟幫助我們實現(xiàn)了一個基于類庫的配置提供程序,我們在列表中沒有單獨列舉這個類庫提供程序。
配置源IConfigurationSource
配置源表示一個單獨的配置集合,可以表示來自內(nèi)存的配置源、來自Json文件的配置源。但是配置源不直接提供對配置的訪問操作,它只有一個接口Build
,該接口一個具體的配置提供程序IConfigurationProvider
,每個配置提供程序負責對配置的讀取、寫入、載入配置、重載配置等訪問操作。
public interface IConfigurationSource { IConfigurationProvider Build(IConfigurationBuilder builder); }
配置提供程序IConfigurationProvider
配置提供程序負責實現(xiàn)配置的設(shè)置、讀取、重載等功能,并以鍵值對形式提供配置。
public interface IConfigurationProvider { //讀取配置 bool TryGet(string key, out string? value); //修改配置 void Set(string key, string? value); //獲取重載配置的Token IChangeToken GetReloadToken(); //載入配置 void Load(); //獲取指定父路徑下的直接子節(jié)點Key,然后 Concat(earlierKeys) 一同返回 IEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys, string? parentPath); }
配置構(gòu)建者IConfigurationBuilder
上面的IConfigurationSource和IConfigurationProvider分別表示一種數(shù)據(jù)源和對一種數(shù)據(jù)源進行讀寫操作。但是一個程序的配置可能來自很多地方,可能一部分配置來自環(huán)境變量、一部分配置來自文件等等。這個時候IConfigurationBuilder配置構(gòu)建者就誕生了,IConfigurationBuilder接口維護了多個配置源,并提供一個Build方法生成一個統(tǒng)一的配置IConfigurationRoot
來統(tǒng)一對整個程序的配置進行讀取、寫入、重載等操作。但是這里大家注意,IConfigurationRoot
對配置的訪問,本質(zhì)上還是通過配置提供程序IConfigurationProvider
來進行的。
假設(shè),當我們查找一個Key為Name的配置,IConfigurationRoot
內(nèi)部會遍歷所有Sources
屬性生成的IConfigurationProvider
,然后依次調(diào)用IConfigurationProvider
的TryGet來獲取Name的具體配置數(shù)據(jù)。
public interface IConfigurationBuilder { //保存Build的一些公開的字典屬性,有需要的化可以使用該字段存放一些變量 IDictionary<string, object> Properties { get; } //來自多個地方的配置源集合 IList<IConfigurationSource> Sources { get; } //向Sources屬性中添加一個配置源 IConfigurationBuilder Add(IConfigurationSource source); //基于所有配置源生成一個全局的配置,供程序讀寫,一般我們都是用這個接口對配置進行讀寫。 IConfigurationRoot Build(); }
配置構(gòu)建者實現(xiàn)類ConfigurationBuilder
在具體的配置構(gòu)建者的Build方法中,我們可以看到,它依次調(diào)用IConfigurationProvider
的Buid方法生成多個配置提供程序IConfigurationProvider
,然后將所有的配置提供程序providers
傳給了ConfigurationRoot
。ConfigurationRoot
正是調(diào)用providers
的一系列方法實現(xiàn)對配置的讀取、寫入、重載等操作。
public class ConfigurationBuilder : IConfigurationBuilder { private readonly List<IConfigurationSource> _sources = new(); public IList<IConfigurationSource> Sources => _sources; public IDictionary<string, object> Properties { get; } = new Dictionary<string, object>(); public IConfigurationBuilder Add(IConfigurationSource source) { ThrowHelper.ThrowIfNull(source); _sources.Add(source); return this; } public IConfigurationRoot Build() { var providers = new List<IConfigurationProvider>(); foreach (IConfigurationSource source in _sources) { IConfigurationProvider provider = source.Build(this); providers.Add(provider); } return new ConfigurationRoot(providers); } }
配置接口IConfiguration
這個接口就是最核心的配置接口,提供了對配置的讀取、寫入、重載等操作,它的實現(xiàn)類是ConfigurationRoot
,上面我們已經(jīng)介紹過,IConfiguration
本身還是通過各個配置提供程序?qū)ε渲眠M行訪問操作。
public interface IConfiguration { //獲取或設(shè)置配置 string? this[string key] { get; set; } //獲取指定key的配置子節(jié)點 IConfigurationSection GetSection(string key); //獲取當前配置的直接子節(jié)點列表 IEnumerable<IConfigurationSection> GetChildren(); //當配置發(fā)生變更時的token IChangeToken GetReloadToken(); }
配置接口IConfigurationRoot
IConfigurationRoot其實是配置的根接口,該接口有個最重要的屬性Providers
負責保存所有的配置提供程序,IConfiguration
對配置的訪問,就是通過遍歷這個Providers
來訪問的。
public interface IConfigurationRoot : IConfiguration { //強制重載所有配置 void Reload(); //所有配置提供程序 IEnumerable<IConfigurationProvider> Providers { get; } }
實現(xiàn)自定義配置提供程序
實現(xiàn)自定義配置提供程序,其實只需要實現(xiàn)三個類就可以,一個是配置源、一個是配置提供程序、一個是針對當前配置的擴展方法。第三個類可有可無,不過我們一般都要實現(xiàn)。我們來參考下基于命令行的配置提供程序類庫的文件。
接下來,我們來實現(xiàn)一個基于數(shù)據(jù)庫的配置提供程序,分別實現(xiàn)配置源DataBaseConfigurationSource
、配置提供程序DataBaseConfigurationExtensions
和擴展方法類DataBaseConfigurationExtensions
,當然在這里我們只做對應(yīng)的演示,沒有實現(xiàn)具體的配置方法。
public class DataBaseConfigurationSource : IConfigurationSource { public IConfigurationProvider Build(IConfigurationBuilder builder) { return new DataBaseConfigurationProvider(); } } public class DataBaseConfigurationProvider : ConfigurationProvider { public override void Load() { base.Load(); //讀取數(shù)據(jù)庫配置 } } public static class DataBaseConfigurationExtensions { public static IConfigurationBuilder AddDb(this IConfigurationBuilder configurationBuilder) { configurationBuilder.Sources.Add(new DataBaseConfigurationSource()); return configurationBuilder; } }
調(diào)用自定義配置程序
static void Main(string[] args) { var builder = new ConfigurationBuilder() .AddDb() .Build(); var value = builder["key"]; }
實戰(zhàn)
基于內(nèi)存的配置程序
基于內(nèi)存的配置程序主要是在內(nèi)存中維護了一個Key-Value鍵值對。
static void MemoryConfig() { List<KeyValuePair<string, string?>>? initialData = new List<KeyValuePair<string, string?>>(); initialData.Add(new KeyValuePair<string, string?>("name", "tom")); IConfigurationRoot configuration = new ConfigurationBuilder() .AddInMemoryCollection(initialData) .Build(); Console.WriteLine("name:" + configuration["name"]); }
調(diào)用如下:
static void Main(string[] args) { MemoryConfig(); }
基于現(xiàn)有的配置提供程序
這個配置提供程序用的相對較少,是微軟在Microsoft.Extensions.Configuration類庫中默認實現(xiàn)的一個配置提供程序,它可以把已經(jīng)存在的配置IConfigurationRoot
封裝成一個配置提供程序。如果需要對針對現(xiàn)有配置快速Copy出一個新配置的話,可以使用這個配置提供程序。
static void ChainedConfig() { List<KeyValuePair<string, string?>>? initialData = new List<KeyValuePair<string, string?>>(); initialData.Add(new KeyValuePair<string, string?>("name", "tom")); //初始化一個已有的配置 IConfigurationRoot configuration = new ConfigurationBuilder() .AddInMemoryCollection(initialData) .Build(); //基于已有的配置,重新生成一個一模一樣的配置。 IConfigurationRoot newConfiguration = new ConfigurationBuilder() .AddConfiguration(configuration) .Build(); Console.WriteLine("name:" + configuration["name"]); }
基于命令行的配置提供程序
基于命令行的配置程序,可以從控制臺的命令行獲取配置,這個配置提供程序可以快速將命令行參數(shù)分解成Key-Value鍵值對。而不需要我們自己手動對字符串進行處理(一般我們會按照空格拆分成數(shù)組,然后按照等號獲取到鍵和值)
//基于命令行的配置 static void CommandLineConfig() { IConfigurationRoot configuration = new ConfigurationBuilder() .AddCommandLine(["name=tom","age=32"]) .Build(); Console.WriteLine("name:" + configuration["name"]);
基于環(huán)境變量的配置提供程序
.NET可以讀取環(huán)境變量中的Key-Value鍵值對,并且可以過濾到指定的前綴來篩選。下面代碼中,程序?qū)虞d環(huán)境變量中以TEST_開頭的所有變量到配置中,我們在系統(tǒng)變量中,新增一個TEST_Name的變量,一定要重啟一下計算機,否則新增的環(huán)境變量不會生效。然后我們的程序就可以讀取到TEST_Name的變量值
static void EnvironmentConfig() { IConfigurationRoot configuration = new ConfigurationBuilder() .AddEnvironmentVariables("Test_") .Build(); Console.WriteLine("name:" + configuration["Name"]); }
基于Json文件的配置提供程序
基于json的配置文件是我們最常用的配置文件格式了,.NET提供了標準的json配置提供程序,我們使用一下代碼從一個app.json文件中加載配置,并且app.json被修改的時候,程序中的配置也會被更新。
//基于Json文件的配置 static void AddJsonFileConfig() { IConfiguration configuration = new ConfigurationBuilder() .AddJsonFile("app.json", optional: true, reloadOnChange: true) .Build(); Console.WriteLine("name:" + configuration["name"]); }
app.json的配置文件內(nèi)容如下:
{ "person": { "name":"caoruipeng", "age":12, "school":"北京大學" }, "name":"tom11" }
基于XML文件的配置提供程序
基于XML的配置文件也是我們比較常用的配置文件格式了,.NET提供了標準的XML配置提供程序,我們使用一下代碼從一個app.xml文件中加載配置,并且app.xml被修改的時候,程序中的配置也會被更新。
//基于XML文件的配置 static void AddXmlFileConfig() { IConfiguration configuration = new ConfigurationBuilder() .AddXmlFile("app.xml", optional: true, reloadOnChange: true) .Build(); Console.WriteLine("name:" + configuration["name"]); }
app.xml的配置文件內(nèi)容如下:
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <config> <name>tom</name> <age>21</age> <school>beijing</school> </config>
基于Ini文件的配置提供程序
Ini配置文件平時 我們使用的比較少,不過微軟還是幫我們提供了基于Ini文件的配置提供程序。
//基于INI文件的配置 static void AddIniFileConfig() { IConfiguration configuration = new ConfigurationBuilder() .AddIniFile("app.ini", optional: true, reloadOnChange: true) .Build(); Console.WriteLine("name:" + configuration["person:name"]); }
app.ini文件的內(nèi)容如下:
[person] name=tom age=27
自定義配置提供程序
官方提供的配置提供程序基本上可以滿足我們的絕大部分需求,但是如果我們的配置存儲在注冊表中、存儲在數(shù)據(jù)庫中,這個時候官方的配置提供程序就無法滿足我們的要求,我們就需要自定義配置提供程序。自定義配置提供程序很簡單,主要包括兩個類:自定義配置源IConfigurationSource
、自定義配置提供程序ConfigurationProvider
以及一個針對當前配置的擴展方法。下面代碼,我們模擬一個基于數(shù)據(jù)庫的配置提供程序,負責從數(shù)據(jù)庫的配置表Config表中讀取配置。當然案例代碼,我們并不是真正的去讀取數(shù)據(jù)庫的表,大家可以自行完善代碼。
//自定義配置源 public class DataBaseConfigurationSource : IConfigurationSource { public IConfigurationProvider Build(IConfigurationBuilder builder) { return new DataBaseConfigurationProvider(); } } //自定義配置提供程序 public class DataBaseConfigurationProvider : ConfigurationProvider { public override void Load() { base.Load(); //讀取數(shù)據(jù)庫配置 } } //數(shù)據(jù)庫配置程序的擴展方法 public static class DataBaseConfigurationExtensions { public static IConfigurationBuilder AddDb(this IConfigurationBuilder configurationBuilder) { configurationBuilder.Sources.Add(new DataBaseConfigurationSource()); return configurationBuilder; } } //調(diào)用案例 static void Main(string[] args) { var builder = new ConfigurationBuilder() .AddDb() .Build(); var value = builder["key"]; }
以上就是.NET Core中配置Configuration的學習指南的詳細內(nèi)容,更多關(guān)于.NET Core配置Configuration的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
.Net6.0+Vue3實現(xiàn)數(shù)據(jù)簡易導入功能全過程
最近在用VUE做一個數(shù)據(jù)導入的功能,下面這篇文章主要給大家介紹了關(guān)于使用.Net6.0+Vue3實現(xiàn)數(shù)據(jù)簡易導入功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2022-09-09在ASP.NET中,設(shè)置Session的過期時間的方法
在ASP.NET中,設(shè)置Session的過期時間的方法,需要的朋友可以參考下2012-12-12asp.net Urlrewriter在虛擬主機上的使用方法
在網(wǎng)上看到,很多朋友在asp.net中做urlrewrite,用的是HttpHandle Server.Transfer的方法。其實這種方法是錯誤的。2009-12-12ASP.NET MVC3網(wǎng)站創(chuàng)建與發(fā)布(1)
這篇文章主要介紹了ASP.NET MVC3網(wǎng)站創(chuàng)建與發(fā)布,根據(jù)文章內(nèi)容大家可以實現(xiàn)發(fā)布網(wǎng)站,感興趣的小伙伴們可以參考一下2015-08-08輕量級ORM框架Dapper應(yīng)用之實現(xiàn)In操作
這篇文章介紹了使用Dapper實現(xiàn)In操作的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-03-03