ASP.NET Core 选项模式源码学习Options Configure(一)
前言
ASP.NET Core 后我们的配置变得更加轻量级了,在ASP.NET Core中,配置模型得到了显著的扩展和增强,应用程序配置可以存储在多环境变量配置中,appsettings.json用户机密等 并可以通过应用程序中的相同界面轻松访问,除此之外,ASP.NET中的新配置系统允许使用Options的强类型设置。
强类型Options
在ASP.NET Core中没有AppSettings["Key"]默认方法,那么推荐的是创建强类型的配置类,去绑定配置项。
public class MyOptions
{
public string Name { get; set; }
public string Url { get; set; }
}
然后我们在appsettings.json中添加如下内容:
{
"MyOptions":
{
"Name": "TestName",
"Url": "TestUrl"
}
}
配置绑定到类
ConfigureServices方法进行配置以绑定到类
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
services.AddControllers();
}
MyOptions只需将IOptions<>类的实例注入控制器中,然后通过Value属性获取Myoptions:
public class WeatherForecastController : ControllerBase
{
private readonly MyOptions _options;
public WeatherForecastController(IOptions<MyOptions> options)
{
_options = options.Value;
}
[HttpGet]
public OkObjectResult Get() {
return Ok(string.Format("Name:{0},Url:{1}", _options.Name,_options.Url));
}
}
Configure
委托配置
//基础注册方式
services.Configure<MyOptions>(o => { o.Url = "MyOptions"; o.Name = "Name111"; });
//指定具体名称
services.Configure<MyOptions>("Option", o => { o.Url = "MyOptions"; o.Name = "Name111"; }) ;
//配置所有实例
services.ConfigureAll<MyOptions>(options =>{ options.Name = "Name1"; options.Url = "Url1";});
通过配置文件配置
// 使用配置文件来注册实例
services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
// 指定具体名称
services.Configure<MyOptions>("Option", Configuration.GetSection("MyOptions"));
PostConfigure
PostConfigure会在Configure注册完之后再进行注册
services.PostConfigure<MyOptions>(o => o.Name = "Name1");
services.PostConfigure<MyOptions>("Option", o => o.Name = "Name1");
services.PostConfigureAll<MyOptions>(o => o.Name = "Name1");
源码解析
IConfigureOptions接口
public interface IConfigureOptions<in TOptions> where TOptions : class
{
void Configure(TOptions options);
}
Configure为方便使用IConfigureOptions注册单例ConfigureNamedOptions
public static IServiceCollection Configure<TOptions>(this IServiceCollection services, string name, Action<TOptions> configureOptions)
where TOptions : class
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
if (configureOptions == null)
{
throw new ArgumentNullException(nameof(configureOptions));
}
services.AddOptions();
services.AddSingleton<IConfigureOptions<TOptions>>(new ConfigureNamedOptions<TOptions>(name, configureOptions));
return services;
}
上面代码IConfigureOptions实现了ConfigureNamedOptions,那我们再来看看内部源码
ConfigureNamedOptions 其实就是把我们注册的Action包装成统一的Configure方法,以方便后续创建Options实例时,进行初始化。
public class ConfigureNamedOptions<TOptions> : IConfigureNamedOptions<TOptions> where TOptions : class
{
public ConfigureNamedOptions(string name, Action<TOptions> action)
{
Name = name;
Action = action;
}
public string Name { get; }
public Action<TOptions> Action { get; }
public virtual void Configure(string name, TOptions options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
// Null name is used to configure all named options.
if (Name == null || name == Name)
{
Action?.Invoke(options);
}
}
public void Configure(TOptions options) => Configure(Options.DefaultName, options);
}
在 services.Configure(Configuration.GetSection("MyOptions")); 我们不指定具体名称的时候默认是如下代码片段
public virtual void Configure(string name, TOptions options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
// Null name is used to configure all named options.
if (Name == null || name == Name)
{
Action?.Invoke(options);
}
}
public void Configure(TOptions options) => Configure(Options.DefaultName, options);
默认使用的是Options.DefaultName
AddOptions默认方法默认为我们注册了一些核心的类
public static IServiceCollection AddOptions(this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<>), typeof(OptionsManager<>)));
services.TryAdd(ServiceDescriptor.Scoped(typeof(IOptionsSnapshot<>), typeof(OptionsManager<>)));
services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptionsMonitor<>), typeof(OptionsMonitor<>)));
services.TryAdd(ServiceDescriptor.Transient(typeof(IOptionsFactory<>), typeof(OptionsFactory<>)));
services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptionsMonitorCache<>), typeof(OptionsCache<>)));
return services;
}
ASP.NET Core 选项模式源码学习Options Configure(一)的更多相关文章
- ASP.NET Core 选项模式源码学习Options IOptionsMonitor(三)
前言 IOptionsMonitor 是一种单一示例服务,可随时检索当前选项值,这在单一实例依赖项中尤其有用.IOptionsMonitor用于检索选项并管理TOption实例的选项通知, IOpti ...
- ASP.NET Core 选项模式源码学习Options IOptions(二)
前言 上一篇文章介绍IOptions的注册,本章我们继续往下看 IOptions IOptions是一个接口里面只有一个Values属性,该接口通过OptionsManager实现 public in ...
- ASP.NET Core 2.1 源码学习之 Options[1]:Configure
配置的本质就是字符串的键值对,但是对于面向对象语言来说,能使用强类型的配置是何等的爽哉! 目录 ASP.NET Core 配置系统 强类型的 Options Configure 方法 Configur ...
- ASP.NET Core 2.1 源码学习之 Options[3]:IOptionsMonitor
前面我们讲到 IOptions 和 IOptionsSnapshot,他们两个最大的区别便是前者注册的是单例模式,后者注册的是 Scope 模式.而 IOptionsMonitor 则要求配置源必须是 ...
- ASP.NET Core 2.1 源码学习之 Options[3]:IOptionsMonitor 【转】
原文链接:https://www.cnblogs.com/RainingNight/p/strongly-typed-options-ioptions-monitor-in-asp-net-core. ...
- ASP.NET Core 2.1 源码学习之 Options[1]:Configure 【转】
原文链接:https://www.cnblogs.com/RainingNight/p/strongly-typed-options-configure-in-asp-net-core.html 配置 ...
- ASP.NET Core 2.1 源码学习之 Options[2]:IOptions
在 上一章 中,介绍了Options的注册,而在使用时只需要注入 IOption<T> 即可: public ValuesController(IOptions<MyOptions& ...
- ASP.NET Core 2.1 源码学习之 Options[2]:IOptions 【转】
原文链接:https://www.cnblogs.com/RainingNight/p/strongly-typed-options-ioptions-in-asp-net-core.html 在 上 ...
- .NET Core 2.1 源码学习:看 SocketsHttpHandler 如何在异步方法中连接 Socket
在 .NET Core 2.1 中,System.Net.Sockets 的性能有了很大的提升,最好的证明是 Kestrel 与 HttpClient 都改为使用 System.Net.Sockets ...
随机推荐
- AutoCad 二次开发 .net 之创建Table
我使用了COM对象来在cad2018中创建table表格,需要的ObjectArx开发包可以在官网上下载,并且需要使用.netframework4.6的库才行. 项目里除了引用常规的Cad开发dll, ...
- linux下安装opencv3.0
查版本gcc --version 需>4.8python 2.7+cmake --version numpy 以上是必须的 linux下安装opencv3.0<pre>https:/ ...
- jquery正确获取iframe里元素的方法
<iframe id="_ae_frame" width="100%" height="100%" frameborder=" ...
- [ISE调试] 在ISE调试过程中,遇到过的error以及消除办法
1.Incompatible IOB's are locked to the same bank 15,具体如右图, 于是去查引脚配置,发现 也就是说,在bank=15的这组IO里面,我既选了LVAM ...
- go中的数据结构通道-channel
1. channel的使用 很多文章介绍channel的时候都和并发揉在一起,这里我想把它当做一种数据结构来单独介绍它的实现原理. channel,通道.golang中用于数据传递的一种数据结构.是g ...
- shell脚本3——调试
bash -x file.sh 这样会把执行到的语句全部打印出来 #!/bin/bash 不会打印的程序块 set -v 需要打印的程序块 set -v 不会打印的程序块
- Pashmak and Graph(dp + 贪心)
题目链接:http://codeforces.com/contest/459/problem/E 题意:给一个带权有向图, 找出其中最长上升路的长度. 题解:先按权值对所有边排序, 然后依次 u -& ...
- 万恶之源-python的进化
列表 列表的增删改查 3. 列列表的嵌套 元组和元组嵌套 5. range ⼀一. 列表 1.1 列表的介绍 列表是python的基础数据类型之⼀一 ,其他编程语⾔言也有类似的数据类型. 比如JS中的 ...
- ssm通用 POM
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven ...
- linux计算机网络基础
OSI7层协议和TCP/IP4层网络协议 第一层:物理层,定义各种物理设备的规范,如通信距离,接口大小等. 第二层:数据链路层,基于mac地址通信是,数据报文封装和相应方式. 第三层:网络层,基于IP ...