ASP.NET Core 源码学习之 Options[2]:IOptions
2017-08-09 07:19
791 查看
在 上一篇 中,介绍了一下Options的注册,而使用时只需要注入 IOption
即可:
而我们在使用的时候,并没有调用
再看一下
其实非常简单,首先使用默认构造函数创建
相关文章:
ASP.NET Core 源码学习之 Options[1]:Configure
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社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
即可:
public ValuesController(IOptions<MyOptions> options){ var opt = options.Value; }
IOptions
IOptions 定义非常简单,只有一个Value属性:
public interface IOptions<out TOptions> where TOptions : class, new() { TOptions Value { get; } }
OptionsManager
而当我们注入IOptions<MyOptions>时,其默认实现则是
OptionsManager<MyOptions>,而且使用的单例模式,在
AddOptions扩展方法中可以看到:
public static IServiceCollection AddOptions(this IServiceCollection services){ services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<>), typeof(OptionsManager<>))); return services; }
而我们在使用的时候,并没有调用
AddOptions扩展方法,那是因为在
WebHostBuilder的
BuildCommonServices方法中进行了调用,具体在Hosting系列中会详细来说。
再看一下
OptionsManager的源码:
public class OptionsManager<TOptions> : IOptions<TOptions> where TOptions : class, new() { private LegacyOptionsCache<TOptions> _optionsCache; public OptionsManager(IEnumerable<IConfigureOptions<TOptions>> setups) { _optionsCache = new LegacyOptionsCache<TOptions>(setups); } public virtual TOptions Value { get { return _optionsCache.Value; } } }
OptionsManager的构造函数中注入了
IConfigureOptions<T>,而这里使用了 IEnumerable 类型,则表示当注册多个时,则为按顺序依次执行。而其
IConfigureOptions则在上一篇已经讲过,是通过
Configure扩展方法进行注册的。而
TOptions的创建工作则是在
LegacyOptionsCache类中:
LegacyOptionsCache
先看代码,胜过千言万语:internal class LegacyOptionsCache<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 LegacyOptionsCache(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); } } }
其实非常简单,首先使用默认构造函数创建
TOptions实例,然后依次执行
IConfigureOptions的
Configure方法,说明最后一次的配置会覆盖之前的配置。而且使用了
LazyInitializer来实现双检锁的效果,保证
TOptions只实例化一次。
总结
本文描述了在 .NET Core Options 系统中,IOptions 的使用及实现原理。IOptions 的实现使用的是单例模式,因此当配置源发生变化时,我们无法获取到最新的配置。如果我们希望能够检测到配置源的变化,并能够自动更新,则可以使用 IOptionsSnapshot相关文章:
ASP.NET Core 源码学习之 Options[1]:Configure
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社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
相关文章推荐
- ASP.NET Core 2.1 源码学习之 Options[2]:IOptions
- ASP.NET Core 2.1 源码学习之 Options[3]:IOptionsMonitor
- ASP.NET Core 2.1 源码学习之 Options[1]:Configure
- ASP.NET Core 源码学习之 Options[3]:IOptionsSnapshot
- ASP.NET Core 源码学习之 Options[4]:IOptionsMonitor
- ASP.NET Core 源码学习之 Options[1]:Configure
- ASP.NET Core 源码学习之 Logging[1]:Introduction
- ASP.NET Core 源码学习之Logging[1]:Introduction
- 【ASP.NET Core 】ASP.NET Core 源码学习之 Logging[1]:Introduction
- ASP.NET Core 源码学习之 Logging[2]:Configure
- ASP.NET Core 源码学习之 Logging[2]:Configure
- ASP.NET Core 源码学习之 Logging[4]:FileProvider
- ASP.NET Core 源码学习之 Logging[3]:Logger
- asp.net core源码飘香:Options组件
- ASP.NET Core 框架源码地址
- 学习ASP.NET Core, 怎能不了解请求处理管道[6]: 管道是如何随着WebHost的开启被构建出来的?
- 2.ASP.NET Core Docker学习-镜像容器与仓库
- 菜鸟入门【ASP.NET Core】5:命令行配置、Json文件配置、Bind读取配置到C#实例、在Core Mvc中使用Options
- ASP.NET Core 2 学习笔记(三)中间件
- 学习ASP.NET Core Razor 编程系列一