国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - Dotnet Core 技術之Dotnet 6.0 深度探索

Dotnet Core 技術之Dotnet 6.0 深度探索

2021-12-29 23:05老王Plus老王Plus的老王 ASP.NET教程

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

Dotnet Core 技術之Dotnet 6.0 深度探索

Dotnet 6.0 大家都裝了沒?

我打算開個專題,系統地寫一寫 Dotnet 6.0 在各個方面的特性,以及全新的開發方式。也是因為最近討論 6.0 比較多,看到很多人的畏難情緒,所以打算寫寫相關的內容。

了解了,就不怕了。

要寫的內容很多,我會分幾篇來寫。

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

ConfigurationManager 是干什么用的?

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

當然,如果我們去看 MSDN 的文檔,會發現 ConfigurationManager 本身實現還是挺復雜的。好在,大多數情況下,這是一個半隱藏的東西,你可能都意識不到你已經用到了它。

那它到底是干什么用的?

這得從 .Net 5.0 的 Configuration 說起。

.Net 5.0 里的 Configuration

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

這里面,我們接觸最多的是兩個:

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

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

簡單來說,IConfigurationBuilder 是這樣的:

  1. public interface IConfigurationBuilder
  2. {
  3. IDictionary Properties { get; }
  4. IList Sources { get; }
  5. IConfigurationBuilder Add(IConfigurationSource source);
  6. IConfigurationRoot Build();
  7. }

而 IConfigurationRoot,里面放的是經過合并的配置值。這個合并需要注意一下,多個配置源逐個加入時,相同名稱的項,后面的配置會覆蓋前面的項。

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

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

這是在 Console 程序中。

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

在默認的 ConfigurationBuilder 實現中,調用 Build() 將遍歷所有的源,加載 Provider 程序,并將它們傳遞給一個新的ConfigurationRoot 實例:

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

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

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

這種架構,會有個小問題。在團隊開發的時候,在沒有統一溝通的情況下,有可能會在多處調用 Build()。當然這也沒什么問題。只不過,正常來說這個沒有必要,畢竟這是在讀文件,會很慢。

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

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

.Net 6.0 里的 ConfigurationManager

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

不過,還是有一點點區別。這里 IConfigurationBuilder 將源保存為 IList:

  1. public interface IConfigurationBuilder
  2. {
  3. IList Sources { get; }
  4. // ...
  5. }

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

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

這樣做可以確保 ConfigurationManager 在改變源的 IList 時,能自動加載源的配置數據。

看一下 ConfigurationManager.AddSource 的定義:

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

這個方法會立即調用 IConfigurationSource 的 Build() 方法來創建 IConfigurationProvider,并加入到源列表中。

下面,這個方法就調用 IConfigurationProvider 的 Load() 方法,將數據加載到 Provider。

這個方法解決了一件事,就是當我們需要從不同的位置向 IConfigurationBuilder 加入各種源時,源只需要加載一次,而且只會加載一次。

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

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

當然,看懂上面的代碼,也就明白兩件事:

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

如果需要對配置的源進行大量的操作,這樣的代價會比較大。不過,這種情況會很不常見。

總結一下

.Net 6.0 引入了一個新的 ConfigurationManager,用來優化配置的構建。

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

這算是一個小禮物,相信也是微軟權衡以后的結果。

原文鏈接:https://mp.weixin.qq.com/s/JO_zq_uV1uuCZg56mUWCTA

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 久久精品亚洲 | 国产一区亚洲二区三区 | 日本www视频 | 中文日韩在线 | 国产精品一区二区免费 | 干干人人| a吖2020天堂网 | 黄视频日本 | 欧美自拍一区 | 国产在线观看一区二区三区 | 久久久久中文字幕 | 欧美在线免费视频 | 干中文字幕 | 久久99视频精品 | 午夜视频在线播放 | 欧美成人激情视频 | 五月婷婷精品 | 久久亚洲视频 | 免费在线一区二区 | 国产精品污www一区二区三区 | 久久精彩 | 久久久久高清 | 亚洲国产aⅴ成人精品无吗 黄色免费在线看 | 日韩美女毛片 | 亚洲 在线 | 电影在线观看免费 | 国产精品女同一区二区久久夜 | 亚洲精品日韩在线 | 美女毛片 | 青青久久久 | 最新免费av网站 | 亚洲视频免费观看 | 亚洲国产精品99久久久久久久久 | 欧美精品在线观看 | 色婷婷综合网 | 3p一区 | 国产日韩欧美不卡 | 国产一区二区三区免费 | 一区二区三区在线观看国产 | 亚洲第一免费播放区 | 免费观看www免费观看 |