麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

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

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

2019-11-14 14:21:07
字體:
來源:轉載
供稿:網友

很久之前寫過一篇介紹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),如此而已。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 精国品产一区二区三区有限公司 | 成年人在线视频 | 亚洲国产精品久久久久制服红楼梦 | 亚洲欧美日韩久久精品第一区 | 草逼一区 | 99国产精品国产免费观看 | 国产女同玩人妖 | 黄网站在线播放视频免费观看 | 久久久久久69 | 爱操影院| 99国产精品自拍 | 国产视频在线观看一区二区三区 | 国产一区在线观看视频 | 黑人一区二区 | 成人精品一区二区 | 国产亚洲欧美视频 | 美女毛片在线观看 | 免费国产一区 | 一区在线视频观看 | 精品国产一区三区 | 日韩 欧美 中文 | 亚洲欧美成aⅴ人在线观看 av免费在线播放 | 国产精品免费视频观看 | 日本成年免费网站 | 免费网站看v片在线a | 久久精品中文字幕一区二区三区 | www69xxxxx| 在线观看第一区 | 鲁丝片一区二区三区免费入口 | 亚洲情在线 | 草草久久久 | 国产在线精品一区二区不卡 | 亚洲精品一区二区三区在线看 | 九九福利视频 | 失禁高潮抽搐喷水h | 爽爽视频免费看 | 在线免费亚洲 | 99成人精品视频 | 日韩99 | 高清av在线| 久久久免费观看完整版 |