自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Dotnet Core 技術(shù)之Dotnet 6.0 深度探索

開發(fā) 前端
引用微軟官方的說法:ConfigurationManager 是用來支持 ASP.Net Core 的新的 WebApplication 模型。這個(gè)模型主要的作用是在一些特定的場(chǎng)景下(后面我們會(huì)說到),用來簡(jiǎn)化 ASP.NET Core 的啟動(dòng)代碼。

[[442733]]

本文轉(zhuǎn)載自微信公眾號(hào)「老王Plus」,作者老王Plus的老王。轉(zhuǎn)載本文請(qǐng)聯(lián)系老王Plus公眾號(hào)。

Dotnet 6.0 大家都裝了沒?

我打算開個(gè)專題,系統(tǒng)地寫一寫 Dotnet 6.0 在各個(gè)方面的特性,以及全新的開發(fā)方式。也是因?yàn)樽罱懻?6.0 比較多,看到很多人的畏難情緒,所以打算寫寫相關(guān)的內(nèi)容。

了解了,就不怕了。

要寫的內(nèi)容很多,我會(huì)分幾篇來寫。

今天是第一篇:ConfigurationManager,配置管理器。

ConfigurationManager 是干什么用的?

引用微軟官方的說法:ConfigurationManager 是用來支持 ASP.Net Core 的新的 WebApplication 模型。這個(gè)模型主要的作用是在一些特定的場(chǎng)景下(后面我們會(huì)說到),用來簡(jiǎn)化 ASP.NET Core 的啟動(dòng)代碼。

當(dāng)然,如果我們?nèi)タ?MSDN 的文檔,會(huì)發(fā)現(xiàn) ConfigurationManager 本身實(shí)現(xiàn)還是挺復(fù)雜的。好在,大多數(shù)情況下,這是一個(gè)半隱藏的東西,你可能都意識(shí)不到你已經(jīng)用到了它。

那它到底是干什么用的?

這得從 .Net 5.0 的 Configuration 說起。

.Net 5.0 里的 Configuration

Configuration 配置,從 3.1 到 5.0,增加了很多很多的配置類型,如果你去 MSDN 上看,有好幾大篇。

這里面,我們接觸最多的是兩個(gè):

  • IConfigurationBuilder - 這個(gè)接口主要用來增加配置源,并在構(gòu)建器上調(diào)用 Build() 來讀取每個(gè)配置源,并形成最終的配置
  • IConfigurationRoot - 這就是上面 Build() 完成后形成的配置,我們會(huì)從這里面讀配置值

在實(shí)際應(yīng)用中,IConfigurationBuilder 通常被我們用做配置源列表的包裝器,最常用的是通過 AddJsonFile(),將配置源添加到源列表中。看到 AddJsonFile(),你是不是想到了什么?

簡(jiǎn)單來說,IConfigurationBuilder 是這樣的:

  1. public interface IConfigurationBuilder 
  2.     IDictionary<string, object> Properties { get; } 
  3.     IList<IConfigurationSource> Sources { get; } 
  4.     IConfigurationBuilder Add(IConfigurationSource source); 
  5.     IConfigurationRoot Build(); 

而 IConfigurationRoot,里面放的是經(jīng)過合并的配置值。這個(gè)合并需要注意一下,多個(gè)配置源逐個(gè)加入時(shí),相同名稱的項(xiàng),后面的配置會(huì)覆蓋前面的項(xiàng)。

在 .Net 5.0 以前,IConfigurationBuilder 和 IConfigurationRoot 接口分別由 ConfigurationBuilder 和 ConfigurationRoot 實(shí)現(xiàn)。使用時(shí)通常是這么寫:

  1. var builder = new ConfigurationBuilder(); 
  2.  
  3. // 加入靜態(tài)值 
  4. builder.AddInMemoryCollection(new Dictionary<string, string> 
  5.     { "MyKey""MyValue" }, 
  6. }); 
  7.  
  8. // 加入文件 
  9. builder.AddJsonFile("appsettings.json"); 
  10.  
  11. IConfigurationRoot config = builder.Build(); 
  12.  
  13. string value = config["MyKey"]; // 取一個(gè)值 
  14. IConfigurationSection section = config.GetSection("SubSection"); // 取一個(gè)節(jié) 

這是在 Console 程序中。

在 ASP.NET Core 中,通常不需要這么顯式的 new 和 Build(),但事實(shí)上也是調(diào)用的這個(gè)接口。

在默認(rèn)的 ConfigurationBuilder 實(shí)現(xiàn)中,調(diào)用 Build() 將遍歷所有的源,加載 Provider 程序,并將它們傳遞給一個(gè)新的ConfigurationRoot 實(shí)例:

  1. public IConfigurationRoot Build() 
  2.     var providers = new List<IConfigurationProvider>(); 
  3.     foreach (IConfigurationSource source in Sources) 
  4.     { 
  5.         IConfigurationProvider provider = source.Build(this); 
  6.         providers.Add(provider); 
  7.     } 
  8.     return new ConfigurationRoot(providers); 

然后,ConfigurationRoot 依次遍歷每個(gè)提供程序并加載配置值:

  1. public class ConfigurationRoot : IConfigurationRoot, IDisposable 
  2.     private readonly IList<IConfigurationProvider> _providers; 
  3.     private readonly IList<IDisposable> _changeTokenRegistrations; 
  4.  
  5.     public ConfigurationRoot(IList<IConfigurationProvider> providers) 
  6.     { 
  7.         _providers = providers; 
  8.         _changeTokenRegistrations = new List<IDisposable>(providers.Count); 
  9.  
  10.         foreach (IConfigurationProvider p in providers) 
  11.         { 
  12.             p.Load(); 
  13.             _changeTokenRegistrations.Add(ChangeToken.OnChange(() => p.GetReloadToken(), () => RaiseChanged())); 
  14.         } 
  15.     } 
  16.     // ...  

這種架構(gòu),會(huì)有個(gè)小問題。在團(tuán)隊(duì)開發(fā)的時(shí)候,在沒有統(tǒng)一溝通的情況下,有可能會(huì)在多處調(diào)用 Build()。當(dāng)然這也沒什么問題。只不過,正常來說這個(gè)沒有必要,畢竟這是在讀文件,會(huì)很慢。

不過,在 .Net 5.0 之前,都是這么做。

可喜的是,在 .Net 6.0 里,微軟也注意到這個(gè)問題,并引入了一個(gè)新的類型:ConfigurationManager。

.Net 6.0 里的 ConfigurationManager

ConfigurationManager 是一個(gè) .Net 6.0 中新的配置類型。這個(gè)類型也同樣實(shí)現(xiàn)了兩個(gè)接口:IConfigurationBuilder 和 IConfigurationRoot。那么,通過這兩個(gè)接口的實(shí)現(xiàn),我們可以簡(jiǎn)化上一節(jié)講到的 .Net 5.0 中的通用模式。

不過,還是有一點(diǎn)點(diǎn)區(qū)別。這里 IConfigurationBuilder 將源保存為 IList:

  1. public interface IConfigurationBuilder 
  2.     IList<IConfigurationSource> Sources { get; } 
  3.     // ... 

這樣做有一個(gè)好處,就是對(duì)于源 IList,就有了 Add() 和 Remove() 方法,我們可以在不知道 ConfigurationManager 的情況下增加和刪除配置提供程序。

  1. private class ConfigurationSources : IList<IConfigurationSource> 
  2.     private readonly List<IConfigurationSource> _sources = new(); 
  3.     private readonly ConfigurationManager _config; 
  4.  
  5.     public ConfigurationSources(ConfigurationManager config) 
  6.     { 
  7.         _config = config; 
  8.     } 
  9.  
  10.     public void Add(IConfigurationSource source) 
  11.     { 
  12.         _sources.Add(source); 
  13.         _config.AddSource(source); // 增加源 
  14.     } 
  15.  
  16.     public bool Remove(IConfigurationSource source) 
  17.     { 
  18.         var removed = _sources.Remove(source); // 刪除源 
  19.         _config.ReloadSources(); // 重新加載源 
  20.         return removed; 
  21.     } 
  22.  
  23.     // ...  

這樣做可以確保 ConfigurationManager 在改變?cè)吹?IList 時(shí),能自動(dòng)加載源的配置數(shù)據(jù)。

看一下 ConfigurationManager.AddSource 的定義:

  1. public class ConfigurationManager 
  2.     private void AddSource(IConfigurationSource source) 
  3.     { 
  4.         lock (_providerLock) 
  5.         { 
  6.             IConfigurationProvider provider = source.Build(this); 
  7.             _providers.Add(provider); 
  8.  
  9.             provider.Load(); 
  10.             _changeTokenRegistrations.Add(ChangeToken.OnChange(() => provider.GetReloadToken(), () => RaiseChanged())); 
  11.         } 
  12.  
  13.         RaiseChanged(); 
  14.     } 

這個(gè)方法會(huì)立即調(diào)用 IConfigurationSource 的 Build() 方法來創(chuàng)建 IConfigurationProvider,并加入到源列表中。

下面,這個(gè)方法就調(diào)用 IConfigurationProvider 的 Load() 方法,將數(shù)據(jù)加載到 Provider。

這個(gè)方法解決了一件事,就是當(dāng)我們需要從不同的位置向 IConfigurationBuilder 加入各種源時(shí),源只需要加載一次,而且只會(huì)加載一次。

上面的代碼是增加源。當(dāng)我們需要 Remove() 源,或者干脆清除掉全部的源 Clear() 時(shí),就需要調(diào)用 ReloadSource():

  1. private void ReloadSources() 
  2.     lock (_providerLock) 
  3.     { 
  4.         DisposeRegistrationsAndProvidersUnsynchronized(); 
  5.  
  6.         _changeTokenRegistrations.Clear(); 
  7.         _providers.Clear(); 
  8.  
  9.         foreach (var source in _sources) 
  10.         { 
  11.             _providers.Add(source.Build(this)); 
  12.         } 
  13.  
  14.         foreach (var p in _providers) 
  15.         { 
  16.             p.Load(); 
  17.             _changeTokenRegistrations.Add(ChangeToken.OnChange(() => p.GetReloadToken(), () => RaiseChanged())); 
  18.         } 
  19.     } 
  20.  
  21.     RaiseChanged(); 

當(dāng)然,看懂上面的代碼,也就明白兩件事:

  • 增加源是代碼最小的,加到列表中就行了 ;
  • 刪除或更改源代碼會(huì)有點(diǎn)大,需要重新遍歷加載所有源。

如果需要對(duì)配置的源進(jìn)行大量的操作,這樣的代價(jià)會(huì)比較大。不過,這種情況會(huì)很不常見。

總結(jié)一下

.Net 6.0 引入了一個(gè)新的 ConfigurationManager,用來優(yōu)化配置的構(gòu)建。

ConfigurationManager 同樣實(shí)現(xiàn)了 ConfigurationBuilder 和 ConfigurationRoot。這算是個(gè)兼容性的設(shè)置,主要是為了支持 WebHostBuilder 和 HostBuilder 中對(duì)配置的調(diào)用。同時(shí),也兼容了早期代碼中的調(diào)用方式。所以,代碼升級(jí)時(shí),相關(guān)配置調(diào)用的部分,如果不想改代碼,是完全可以的。而如果想做點(diǎn)改動(dòng),就換成使用 ConfigurationManager,或者通過 WebApplicationBuilder 來加載(會(huì)自動(dòng)調(diào)用 ConfigurationManager),應(yīng)用程序會(huì)有更好的性能。

這算是一個(gè)小禮物,相信也是微軟權(quán)衡以后的結(jié)果。

 

責(zé)任編輯:武曉燕 來源: 老王Plus
相關(guān)推薦

2021-09-06 10:22:47

匿名對(duì)象編程

2024-05-21 10:23:02

反射技術(shù).NET編程語言

2022-03-11 09:22:55

令牌Dotnet線程

2021-07-07 08:01:51

命令行Dotnet Core控制臺(tái)

2013-03-15 10:57:13

AJAXDotNet

2024-05-27 09:52:57

反射技術(shù).NET動(dòng)態(tài)庫(kù)

2021-01-13 08:11:45

項(xiàng)目結(jié)構(gòu)類型

2021-01-20 08:16:06

異步Dotnet Core多路徑

2021-03-17 08:12:03

架構(gòu)Dotnet洋蔥

2021-03-03 08:13:57

模式垃圾回收

2021-03-10 07:20:44

數(shù)據(jù)定位匹配

2021-06-02 08:07:59

LinuxService應(yīng)用

2017-02-14 16:39:56

docker容器化主機(jī)

2011-04-20 17:15:21

并行計(jì)算

2021-02-03 08:12:23

函數(shù)委托Dotnet

2011-04-21 09:13:14

并行計(jì)算

2017-02-14 15:51:16

docker開發(fā)調(diào)試

2021-01-27 08:12:04

Dotnet函數(shù)數(shù)據(jù)

2022-11-22 08:01:34

dotNET 7API

2021-03-11 08:51:21

微軟漏洞dotnet
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)