.NET 6 中的 ConfigurationManager
.NET 6 中的 ConfigurationManager
Intro
.NET 6 為了 Minimal API 引入了一些新東西,其中就包含了一個(gè)全新的配置對(duì)象 ConfigurationManager
這并不是 .NET Framework 里的靜態(tài)類?ConfigurationManager,而是 .NET Core 里的配置 Microsoft.Extensions.Configuration 中的一個(gè)新類型,新的 ConfigurationManager 對(duì)象是之前的 ConfigurationBuilder 和 ConfigurationRoot 的結(jié)合
Implement
API Proposal:
namespace?Microsoft.Extensions.Configuration { +????public?sealed?class?ConfigurationManager?:?IConfigurationRoot,?IConfigurationBuilder,?IDisposable +????{ +????????public?ConfigurationManager(); +????????public?string??this[string?key]?{?get;?set;?} +????????public?IConfigurationSection?GetSection(string?key); +????????public?void?Dispose(); +????}Implement:
public?sealed?class?ConfigurationManager?:?IConfigurationBuilder,?IConfigurationRoot,?IDisposable {private?readonly?ConfigurationSources?_sources;private?readonly?ConfigurationBuilderProperties?_properties;private?readonly?object?_providerLock?=?new();private?readonly?List<IConfigurationProvider>?_providers?=?new();private?readonly?List<IDisposable>?_changeTokenRegistrations?=?new();private?ConfigurationReloadToken?_changeToken?=?new();///?<summary>///?Creates?an?empty?mutable?configuration?object?that?is?both?an?<see?cref="IConfigurationBuilder"/>?and?an?<see?cref="IConfigurationRoot"/>.///?</summary>public?ConfigurationManager(){_sources?=?new?ConfigurationSources(this);_properties?=?new?ConfigurationBuilderProperties(this);//?Make?sure?there's?some?default?storage?since?there?are?no?default?providers.this.AddInMemoryCollection();AddSource(_sources[0]);}//?... }ConfigurationManager在添加 ConfigurationSource 的時(shí)候也會(huì)注冊(cè) IConfigurationProvider,這樣在添加 Source 之后就能夠拿到 Configuration 中的配置了,在實(shí)現(xiàn)上,微軟封裝了一個(gè)私有的 ConfigurationSource 的類型,這里我們看一下注冊(cè)配置源的代碼
private?class?ConfigurationSources?:?IList<IConfigurationSource> {private?readonly?List<IConfigurationSource>?_sources?=?new();private?readonly?ConfigurationManager?_config;public?ConfigurationSources(ConfigurationManager?config){_config?=?config;}public?IConfigurationSource?this[int?index]{get?=>?_sources[index];set{_sources[index]?=?value;_config.ReloadSources();}}public?void?Add(IConfigurationSource?source){_sources.Add(source);_config.AddSource(source);}//?... }ConfigurationManager 中的 AddSource 方法實(shí)現(xiàn)如下:
IConfigurationBuilder?IConfigurationBuilder.Add(IConfigurationSource?source) {_sources.Add(source????throw?new?ArgumentNullException(nameof(source)));return?this; }private?void?RaiseChanged() {var?previousToken?=?Interlocked.Exchange(ref?_changeToken,?new?ConfigurationReloadToken());previousToken.OnReload(); }//?Don't?rebuild?and?reload?all?providers?in?the?common?case?when?a?source?is?simply?added?to?the?IList. private?void?AddSource(IConfigurationSource?source) {lock?(_providerLock){var?provider?=?source.Build(this);_providers.Add(provider);provider.Load();_changeTokenRegistrations.Add(ChangeToken.OnChange(()?=>?provider.GetReloadToken(),?()?=>?RaiseChanged()));}RaiseChanged(); }可以看到每次新加一個(gè)配置源的時(shí)候,都會(huì)去構(gòu)建對(duì)應(yīng)的一個(gè) IConfigurationProvider 而且會(huì)去加載配置數(shù)據(jù)并注冊(cè)配置更新事件,所以我們注冊(cè)完配置之后才能夠獲取到配置,更多實(shí)現(xiàn)細(xì)節(jié)參考 Github 上的源碼:https://github.com/dotnet/runtime/blob/v6.0.0-rc.1.21451.13/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationManager.cs
Sample
來(lái)看下面使用時(shí)的 Sample 吧,非常的簡(jiǎn)單
const?string?testKey?=?"test";var?configuration?=?new?ConfigurationManager(); Console.WriteLine(configuration[testKey]);configuration.AddInMemoryCollection(new?Dictionary<string,?string>() {{?testKey,?"test"?} }); Console.WriteLine(configuration[testKey]); Console.ReadLine();輸出結(jié)果如下:
第一次輸出的時(shí)候還沒有注冊(cè)配置輸出的是空,第一次輸出的時(shí)候已經(jīng)注冊(cè)了配置輸出的是我們配置的值
代碼示例在可以從 Github 獲取 https://github.com/WeihanLi/SamplesInPractice/blob/master/net6sample/ConfigurationManagerSample/Program.cs
More
目前來(lái)說(shuō),ConfigurationManager 對(duì)象主要是為了 .NET 6 的 Minimal API 的需要,.NET 6 的 Minimal API 里用了這個(gè),可以參考:https://github.com/dotnet/aspnetcore/blob/v6.0.0-rc.1.21452.15/src/DefaultBuilder/src/WebApplicationBuilder.cs ,但就像上面的示例一樣,我們也是可以直接使用的,而且原來(lái)的 IConfigurationBuilder 依然是可以用的,無(wú)需擔(dān)心升級(jí)到 .NET 6 會(huì) break 的問題。
對(duì)于需要用到配置的測(cè)試程序直接用 ConfigurationManager 會(huì)更為簡(jiǎn)單一些,不需要先聲明一個(gè) ConfigurationBuilder 的對(duì)象注冊(cè)好配置之后再構(gòu)建一個(gè) IConfiguration 對(duì)象,直接用一個(gè)對(duì)象就可以了,至少?gòu)奈覀儗懘a的角度會(huì)簡(jiǎn)單很多,但是性能會(huì)稍差一些,注冊(cè)的配置源越多越明顯,因?yàn)?ConfigurationManager 每次注冊(cè)配置源的時(shí)候都會(huì)去構(gòu)建和注冊(cè) IConfigurationProvider ?而 IConfigurationBuilder 則是在最后 Build 的時(shí)候才構(gòu)建一次,不過通常我們的配置也只是啟動(dòng)時(shí)只用配置一次,個(gè)人認(rèn)為是可以接受的
References
https://github.com/dotnet/runtime/blob/v6.0.0-rc.1.21451.13/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationManager.cs
https://github.com/dotnet/runtime/blob/v6.0.0-rc.1.21451.13/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationRoot.cs
https://github.com/dotnet/runtime/blob/v6.0.0-rc.1.21451.13/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationBuilder.cs
https://github.com/dotnet/runtime/pull/55338
https://github.com/dotnet/runtime/issues/51770
https://github.com/dotnet/aspnetcore/blob/v6.0.0-rc.1.21452.15/src/DefaultBuilder/src/BootstrapHostBuilder.cs
https://github.com/dotnet/aspnetcore/blob/v6.0.0-rc.1.21452.15/src/DefaultBuilder/src/WebApplicationBuilder.cs
https://github.com/WeihanLi/SamplesInPractice/blob/master/net6sample/ConfigurationManagerSample/Program.cs
總結(jié)
以上是生活随笔為你收集整理的.NET 6 中的 ConfigurationManager的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大前端快闪:package.json文件
- 下一篇: Dapr牵手.NET学习笔记:状态管理之