国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

[Asp.net5]Options-配置文件(2)

2019-11-14 14:31:01
字體:
來源:轉載
供稿:網友

很久之前寫過一篇介紹Options的文章,2016年再打開發現很多變化。增加了新類,增加OptionMonitor相關的類。今天就對于這個現在所謂的新版本進行介紹。

老版本的傳送門([asp.net 5] Options-配置文件之后昂的配置)。

首先上一個圖:

*綠線是繼承關系,藍線是關聯關系。

我們把上面切成2大部分。

Option部分

這部分分為倆部分,第一部分直接創建Options,該部分通過Options靜態類創建一個OptionsWrapper類,之后將(IOptions,OptionsWrapper)進行注入。這部分是DI的實體注入,很簡單,沒有什么可說的,此處應用非常常見的“工廠模式”。

第二部分是將(IOptions,OptionsManager)進行注入。我們OptionsManager會使用IEnumerable<IConfigureOptions<TOptions>>作為參數,而內部返回的是OptionsCache類型的對象,此處應用非常常見的“代理模式

    internal class OptionsCache<TOptions> where TOptions : class, new()    {        PRivate readonly Func<TOptions> _createCache;        private object _cacheLock = new object();        private bool _cacheInitialized;        private TOptions _options;        private IEnumerable<IConfigureOptions<TOptions>> _setups;        public OptionsCache(IEnumerable<IConfigureOptions<TOptions>> setups)        {            _setups = setups;            _createCache = CreateOptions;        }        private TOptions CreateOptions()        {            var result = new TOptions();            if (_setups != null)            {                foreach (var setup in _setups)                {                    setup.Configure(result);                }            }            return result;        }        public virtual TOptions Value        {            get            {                return LazyInitializer.EnsureInitialized(                    ref _options,                    ref _cacheInitialized,                    ref _cacheLock,                    _createCache);            }        }    }
OptionsCache

此處附錄OptionsCache代碼,里面(IConfigureOptions,ConfigureOptions)已經進行注入了。而ConfigureOptions代碼如下:

    public class ConfigureOptions<TOptions> : IConfigureOptions<TOptions> where TOptions : class    {        public ConfigureOptions(Action<TOptions> action)        {            if (action == null)            {                throw new ArgumentNullException(nameof(action));            }            Action = action;        }        public Action<TOptions> Action { get; private set; }        public virtual void Configure(TOptions options)        {            if (options == null)            {                throw new ArgumentNullException(nameof(options));            }            Action.Invoke(options);        }    }
ConfigureOptions

而ConfigureOptions實際上只是對Action<TOptions>的封裝吧了(這里是不是可以理解為適配器)。

*為什么要傳遞Action<T>進行配置?我的理解是因為延時性延時的概念就是,你做的修改不是立馬生效,以至于配置的時候,我們都不用考慮先后順序。

OptionsMonitor部分

OptionsMonitor是對Options的監視器。我決定這部分好像一個調度者模式??

IOptionsChangeTokenSource

OptionsMonitor代碼如下:

    public class OptionsMonitor<TOptions> : IOptionsMonitor<TOptions> where TOptions : class, new()    {        private OptionsCache<TOptions> _optionsCache;        private readonly IEnumerable<IConfigureOptions<TOptions>> _setups;        private readonly IEnumerable<IOptionsChangeTokenSource<TOptions>> _sources;        public OptionsMonitor(IEnumerable<IConfigureOptions<TOptions>> setups, IEnumerable<IOptionsChangeTokenSource<TOptions>> sources)        {            _sources = sources;            _setups = setups;            _optionsCache = new OptionsCache<TOptions>(setups);        }        public TOptions CurrentValue        {            get            {                return _optionsCache.Value;            }        }        public IDisposable OnChange(Action<TOptions> listener)        {            var disposable = new ChangeTrackerDisposable();            foreach (var source in _sources)            {                Action<object> callback = null;                IDisposable previousSubscription = null;                callback = (s) =>                {                    // The order here is important. We need to take the token and then apply our changes BEFORE                    // registering. This prevents us from possible having two change updates to process concurrently.                    //                    // If the token changes after we take the token, then we'll process the update immediately upon                    // registering the callback.                    var token = source.GetChangeToken();                    // Recompute the options before calling the watchers                    _optionsCache = new OptionsCache<TOptions>(_setups);                    listener(_optionsCache.Value);                    // Remove the old callback after its been fired                    var nextSubscription = token.RegisterChangeCallback(callback, s);                    disposable.Disposables.Add(nextSubscription);                    disposable.Disposables.Remove(previousSubscription);                    previousSubscription = nextSubscription;                };                previousSubscription = source.GetChangeToken().RegisterChangeCallback(callback, state: null);                disposable.Disposables.Add(previousSubscription);            }            return disposable;        }    }
OptionsMonitor

通過IOptionsChangeTokenSource的IChangeToken對象發出更改請求,之后Action<TOptions> listener進行數據更改。

Onchange方法,實現上就是每次調用都會創建一個新的IDisposable(ChangeTrackerDisposable),如此而已。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 开化县| 特克斯县| 尚志市| 浦县| 乌拉特中旗| 双鸭山市| 徐州市| 澜沧| 谷城县| 墨江| 中卫市| 宁河县| 昌乐县| 海安县| 衡南县| 南平市| 金川县| 庐江县| 富民县| 武宣县| 湖南省| 汤阴县| 盘山县| 观塘区| 沙坪坝区| 顺昌县| 达州市| 永登县| 南汇区| 广汉市| 天峨县| 永川市| 梅河口市| 合肥市| 阳东县| 肥东县| 灵武市| 江都市| 大埔县| 正安县| 都匀市|