日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET Core 源码学习之 Options[3]:IOptionsSnapshot

發(fā)布時間:2023/12/4 asp.net 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Core 源码学习之 Options[3]:IOptionsSnapshot 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2017-06-28 更新:
OptionsSnapshot?已改為 OptionsManager?變更詳情
IOptionsCache?已改為 IOptionsMonitorCache?變更詳情

在?上一章?中,介紹了?IOptions?的使用, 而我們知道,在 ConfigurationBuilder 的 AddJsonFile 中,有一個 reloadOnChange 參數(shù),設(shè)置為 true 時,在配置文件發(fā)生變化時,會自動更新 IConfigurationRoot ,這是一個非常棒的特性,遺憾的是?IOptions?在配置源發(fā)生變化時,并不會進行更新。好在,微軟還為我們提供了?IOptionsSnapshot?,本章就來探索一下其源碼。

IOptionsSnapshot

IOptionsSnapshot?繼承自IOptions,并擴展了一個Get方法:

public interface IOptionsSnapshot<out TOptions> : IOptions<TOptions> where TOptions : class, new() { ? ?TOptions Get(string name); }

看到Get方法的Name參數(shù),我想大家便會想到在?第一章?中所介紹的指定Name的Configure方法,這便是它的用武之地了,通過Name的不同,來配置同一Options類型的多個實例。

那?IOptionsSnapshot?又是如何實現(xiàn)配置的同步的呢?別急,先看一下它與?IOption?的區(qū)別:

services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<>), typeof(OptionsManager<>))); services.TryAdd(ServiceDescriptor.Scoped(typeof(IOptionsSnapshot<>), typeof(OptionsSnapshot<>)));

首先很明顯的是:一個是單例,一個指定作用域。其次,IOptionsSnapshot?的實現(xiàn)者是?OptionsSnapshot。

OptionsSnapshot

從名字上來看,便知道它保存的只是一份快照,先看下源碼:

public class OptionsSnapshot<TOptions> : IOptionsSnapshot<TOptions> where TOptions : class, new() { ?
?private readonly IOptionsFactory<TOptions> _factory; ?
??private readonly OptionsCache<TOptions> _cache = new OptionsCache<TOptions>(); ?
??
???public OptionsSnapshot(IOptionsFactory<TOptions> factory) ? ?{_factory = factory;} ? ?
???
???public TOptions Value => Get(Options.DefaultName); ?
???
??? ?public virtual TOptions Get(string name) ? ?{ ? ? ?
??? ? ?if (name == null){ ? ? ?
??? ? ?? ? ?throw new ArgumentNullException(nameof(name));} ? ?
??? ? ?// Store the options in our instance cachereturn _cache.GetOrAdd(name, () => _factory.Create(name));} }

代碼很簡單,Options?的創(chuàng)建是通過?IOptionsFactory?來實現(xiàn)的,而?Options?的實例是通過?OptionsCache來保存的。那便去看下他們的源碼。

IOptionsFactory

public interface IOptionsFactory<TOptions> where TOptions : class, new() { ? ?
TOptions Create(string name); }

public class OptionsFactory<TOptions> : IOptionsFactory<TOptions> where TOptions : class, new() { ?

?private readonly IEnumerable<IConfigureOptions<TOptions>> _setups; ?
??private readonly IEnumerable<IPostConfigureOptions<TOptions>> _postConfigures; ?
??
?? ?public OptionsFactory(IEnumerable<IConfigureOptions<TOptions>> setups, IEnumerable<IPostConfigureOptions<TOptions>> postConfigures) ? ?{_setups = setups;_postConfigures = postConfigures;} ? ?
?? ?
?? ?public TOptions Create(string name) ? ?{ ? ?
?? ? ? ?var options = new TOptions(); ? ?
?? ? ? ?foreach (var setup in _setups){ ? ? ? ?
?? ? ? ?? ?if (setup is IConfigureNamedOptions<TOptions> namedSetup){namedSetup.Configure(name, options);} ? ? ? ?
?? ? ? ?? ??else if (name == Options.DefaultName) ? ?
? ? ? ? ? ?
{setup.Configure(options);}} ? ?
?? ? ? ?foreach (var post in _postConfigures){post.PostConfigure(name, options);} ? ? ? ?return options;} }

IOptionsFactory?的默認實現(xiàn)類是?OptionsFactory,在創(chuàng)建Options時,先執(zhí)行所有的Configure方法,然后執(zhí)行PostConfigure方法。在?第一章?中講的PostConfigure方法,也在這里派上用場了。

OptionsCache

OptionsCache?用來緩存?Options?的實例,相當于一個優(yōu)化的Options字典,并使用Lazy實現(xiàn)了延遲初始化,看代碼:

public class OptionsCache<TOptions> : IOptionsCache<TOptions> where TOptions : class{ ?

?private readonly ConcurrentDictionary<string, Lazy<TOptions>> _cache = new ConcurrentDictionary<string, Lazy<TOptions>>(StringComparer.Ordinal); ? ?
?
?public virtual TOptions GetOrAdd(string name, Func<TOptions> createOptions) ? ?{ ? ? ?
??if (name == null) throw new ArgumentNullException(nameof(name)); ?
??? ? ?if (createOptions == null) throw new ArgumentNullException(nameof(createOptions)); ? ?
??? ? ?? ?return _cache.GetOrAdd(name, new Lazy<TOptions>(createOptions)).Value;} ?
???
????public virtual bool TryAdd(string name, TOptions options) ? ?{ ?
????? ? ?if (name == null)
????? ? ? ? throw new ArgumentNullException(nameof(name)); ? ?
????? ? ?if (options == null) throw new ArgumentNullException(nameof(options)); ? ? ?
????? ? ? ??return _cache.TryAdd(name, new Lazy<TOptions>(() => options));} ?
????
?????public virtual bool TryRemove(string name) ? ?{ ? ?
????? ? ?if (name == null) throw new ArgumentNullException(nameof(name)); ? ? ? ? ? ? ? ??return _cache.TryRemove(name, out var ignored);} }

總結(jié)

IOptionsSnapshot?通過注冊為一個作用域內(nèi)的單例模式,來保證當配置發(fā)生變化時,下一個請求可以獲取到最新的配置。其實在?2.0-preview2?中,OptionsSnapshot?使用了?IOptionsChangeTokenSource?模式,來監(jiān)聽配置的變化,當發(fā)生變化清空?OptionsCache?中的緩存,來實現(xiàn)?Options?的自動更新。當時我還感到困擾:“OptionsSnapshot既然能夠做到配置的更新,怎么還注冊成Scope實例呢?”。而現(xiàn)在缺少了?IOptionsChangeTokenSource?模式的即時更新,或許讓我們感覺不是那么爽,當然也有一個致命的問題,就是當我們在一個自定義的類中使用了?IOptionsSnapshot?,并且這個類本身是以單例的形式注冊的,那么便永遠獲取不到最新的配置了。不過,我們還有最后一個大殺器:?IOptionsMonitor,來滿足我們極致的需求,哈哈,下一篇就來介紹一下它。

相關(guān)文章:?

  • ASP.NET Core 源碼學習之 Options[1]:Configure

  • ASP.NET Core 源碼學習之 Options[2]:IOptions

  • ASP.NET Core MVC 源碼學習:詳解 Action 的匹配

  • asp.net core源碼飄香:從Hosting開始

  • asp.net core源碼飄香:Configuration組件

  • asp.net core源碼飄香:Options組件

  • asp.net core源碼飄香:Logging組件

原文地址:http://www.cnblogs.com/RainingNight/p/strongly-typed-options-ioptions-in-asp-net-core.html


.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關(guān)注

總結(jié)

以上是生活随笔為你收集整理的ASP.NET Core 源码学习之 Options[3]:IOptionsSnapshot的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。