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

王朝学院·作者佚名  2016-08-28
窄屏简体版  字體: 小  |  中  |  大  |  超大  

很久之前写过一篇介绍Options的文章,2016年再打开发现很多变化。增加了新类,增加OptionMonitor相关的类。今天就对于这个现在所谓的新版本进行介绍。

老版本的传送门([asp.net5] Options-配置文件之后昂的配置)。

首先上一个图:

[flash=500,400]http://s1.knowsky.com/20160211/kz43vcwtuqw07.png[/flash]

*绿线是继承关系,蓝线是关联关系。

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

Option部分

这部分分为俩部分,第一部分直接创建Options,该部分通过Options静态类创建一个OptionsWrapper类,之后将(IOptions,OptionsWrapper)进行注入。这部分是DI的实体注入,很简单,没有什么可说的,此处应用非常常见的“工厂模式”。

第二部分是将(IOptions,OptionsManager)进行注入。我们OptionsManager会使用IEnumerable<IConfigureOptions<TOptions>>作为参数,而内部返回的是OptionsCache类型的对象,此处应用非常常见的“代理模式”

[flash=500,400]http://s1.knowsky.com/20160211/ai0bn3ixxoo07.gif[/flash][flash=500,400]http://s1.knowsky.com/20160211/01ue00yx1x307.gif[/flash]internalclassOptionsCache<TOptions>whereTOptions :class,new()

{PRivatereadonlyFunc<TOptions>_createCache;privateobject_cacheLock =newobject();privatebool_cacheInitialized;privateTOptions _options;privateIEnumerable<IConfigureOptions<TOptions>>_setups;publicOptionsCache(IEnumerable<IConfigureOptions<TOptions>>setups)

{

_setups=setups;

_createCache=CreateOptions;

}privateTOptions CreateOptions()

{varresult =newTOptions();if(_setups !=null)

{foreach(varsetupin_setups)

{

setup.Configure(result);

}

}returnresult;

}publicvirtualTOptions Value

{get{returnLazyInitializer.EnsureInitialized(ref_options,ref_cacheInitialized,ref_cacheLock,

_createCache);

}

}

}

OptionsCache

此处附录OptionsCache代码,里面(IConfigureOptions,ConfigureOptions)已经进行注入了。而ConfigureOptions代码如下:

[flash=500,400]http://s1.knowsky.com/20160211/ai0bn3ixxoo07.gif[/flash][flash=500,400]http://s1.knowsky.com/20160211/01ue00yx1x307.gif[/flash]publicclassConfigureOptions<TOptions> : IConfigureOptions<TOptions>whereTOptions :class{publicConfigureOptions(Action<TOptions>action)

{if(action ==null)

{thrownewArgumentNullException(nameof(action));

}

Action=action;

}publicAction<TOptions> Action {get;privateset; }publicvirtualvoidConfigure(TOptions options)

{if(options ==null)

{thrownewArgumentNullException(nameof(options));

}

Action.Invoke(options);

}

}

ConfigureOptions

而ConfigureOptions实际上只是对Action<TOptions>的封装吧了(这里是不是可以理解为适配器)。

*为什么要传递Action<T>进行配置?我的理解是因为延时性。延时的概念就是,你做的修改不是立马生效,以至于配置的时候,我们都不用考虑先后顺序。

OptionsMonitor部分

OptionsMonitor是对Options的监视器。我决定这部分好像一个调度者模式??。

的IOptionsChangeTokenSource

OptionsMonitor代码如下:

[flash=500,400]http://s1.knowsky.com/20160211/ai0bn3ixxoo07.gif[/flash][flash=500,400]http://s1.knowsky.com/20160211/01ue00yx1x307.gif[/flash]publicclassOptionsMonitor<TOptions> : IOptionsMonitor<TOptions>whereTOptions :class,new()

{privateOptionsCache<TOptions>_optionsCache;privatereadonlyIEnumerable<IConfigureOptions<TOptions>>_setups;privatereadonlyIEnumerable<IOptionsChangeTokenSource<TOptions>>_sources;publicOptionsMonitor(IEnumerable<IConfigureOptions<TOptions>> setups, IEnumerable<IOptionsChangeTokenSource<TOptions>>sources)

{

_sources=sources;

_setups=setups;

_optionsCache=newOptionsCache<TOptions>(setups);

}publicTOptions CurrentValue

{get{return_optionsCache.Value;

}

}publicIDisposable OnChange(Action<TOptions>listener)

{vardisposable =newChangeTrackerDisposable();foreach(varsourcein_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.vartoken =source.GetChangeToken();//Recompute the options before calling the watchers_optionsCache =newOptionsCache<TOptions>(_setups);

listener(_optionsCache.Value);//Remove the old callback after its been firedvarnextSubscription =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);

}returndisposable;

}

}

OptionsMonitor

通过IOptionsChangeTokenSource的IChangeToken对象发出更改请求,之后Action<TOptions> listener进行数据更改。

Onchange方法,实现上就是每次调用都会创建一个新的IDisposable(ChangeTrackerDisposable),如此而已。

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航