说明
个人学习记录,可能有理解偏差,有误地方,望大佬可指正
Configuration
Configuration接口UML图
Configuration 应为 源的统一构建助手,源的构建配置,源的数据提供出口,源的统一数据提供总出口,源的节点描述(源指的是数据源)
IConfigurationBuilder:源的统一构建助手
源的统一构建助手必然就应该负责构建源,以及构建源的统一数据提供总出口
也就是该接口中依赖的 IConfigurationSource(构建源) 和 IConfigurationRoot(源的统一数据提供总出口)
IConfigurationSource:源的构建配置
实现IConfigurationSource接口,并且在实现类中添加构建 源的数据提供出口类(IConfigurationProvider) 的必要参数,再使用该参数进行构建 源的数据提供出口类(IConfigurationProvider)
IConfigurationProvider:源的数据提供出口
实现IConfigurationProvider接口,主要是加载对应 path 下的内容,尝试获取对应key的值以及set对应key的值。
IConfigurationRoot:源的统一数据提供总出口
实现IConfigurationRoot接口,可以拥有所有源的能力。每个源的load()会在IConfigurationRoot实现类的构造函数中被触发,而IConfigurationRoot接口又实现了IConfiguration接口,所以IConfiguration接口提供了获取源节点描述信息以及源对应key的value信息的能力,所以在IConfigurationRoot接口实现类是源的统一数据提供总出口
IConfiguration 和 IConfigurationSection:源的节点描述
IConfiguration 和 IConfigurationSection构成了源节点的描述。为什么这样说呢?
IConfigurationSection 其实就是可以看作源的 节点或子节点描述,要注意的是IConfiguration实际上还实现了IConfiguration,而IConfiguration身上是拥有获取子节点的能力的(GetChildren()方法)。通过IConfiguration中的GetSection()方法获取到某个节点或子节点的描述,再通过
string? this[string key] { get; set; }
获取对应值IConfiguration 更加可以看作 源的数据获取器
string? this[string key] { get; set; }
获取某个节点对应key的value值GetSection(string key)
获取某个节点的节点描述,可以获取到他的所有children的节点描述,再获取他的值实际上IConfiguration和IConfigurationSection最终都会调回到IConfigurationProvider接口的
tryGet()
方法可以理解为下图:
总结:
- 对内的核心类其实就是IConfigurationBuilder接口实现类以及 IConfigurationRoot接口实现类
- IConfigurationBuilder接口 实现了IConfiguration接口,可以获取到 源的整体节点描述,并存储了所有的 源的数据提供出口(IConfigurationProvide)
- IConfigurationBuilder接口则是通过IConfigurationSource构建 IConfigurationProvider,再赋值到IConfigurationRoot接口实现类中,完成源的统一构建助手的任务
- 对外的核心类其实就是 IConfiguration接口(注意:IConfigurationRoot也实现了IConfiguration接口 )
- 提供了一系列的查询方法
string? this[string key] { get; set; }
GetSection(string key):IConfigurationSection
GetChildren():IEnumerable<IConfigurationSection>
Q&A
-
如何获取Configuration中的数据
- IConfiguration 中
[key]
直接获取 - IConfigurationSection 中
[key]
直接获取 - IConfiguration 中
getchilder
再进行,[key]
获取
- IConfiguration 中
-
我们常见的
builder.Configuration.AddJsonFile
他到底完成的是一件什么样子的事- 实际上应该就是向 IConfigurationBuilder中的
IList<IConfigurationSource> Sources
加入 jsonConfigurationSource ,在调用IConfigurationBuilder#build()
方法的时候就会创建对应的IConfigurationProvider
- 实际上应该就是向 IConfigurationBuilder中的
-
Configuration整一个东西的整体样貌
Option
简介
关于
IOption
:
- IOption被称为
选项模型
,它是在.netcore中引入的。它的作用是给我们的应用程序提供配置,这个配置就是一个个的对象模型。关于“依赖注入”和“选项模型”:
- “选项模型”本身是构筑在“依赖注入”框架上的,所以我们要想使用“选项模型”就必须先引入“依赖注入”框架。
关于“配置”和“选项模型”:
IConfiguration
和IOption
在.netcore中被称为配置选项,前者表示配置,后者表示选项模型。它们二者在.netcore中是一对基石。虽然它们二者的关系紧密,而且选项模型
的数据来源大多来自配置
,但它们二者之间并没有直接的依赖关系,也就是说它们二者任何一个都可以单独拿出来使用。关于选项模型的包:
选项模型本身就一个nuget包:
Microsoft.Extensions.Options
。选项模型是运行在依赖注入框架上的,所以它引用“依赖注入”框架的抽象包
``Microsoft.Extensions.DependencyInjection.Abstractions`
- 如果是控制台程序,为了能使用“选项模型”,我们还要再手动引入“依赖注入”框架的实现包:
Microsoft.Extensions.DependencyInjection
- 如果我们想让“配置”为“选项模型”提供数据来源,那么我们需要手动引入扩展包:
Microsoft.Extensions.Options.ConfigurationExtensions
- 如果想用已经定义好的一些参数配置校验,可以手动引入扩展包:
Microsoft.Extensions.Options.DataAnnotations
- 在使用IConfiguration作为数据源的时候,如果需要用到一些JSON扩展到东西,可以引入JSON配置包:
Microsoft.Extensions.Configuration.Json
使用介绍
通过注入IConfiguration的方式读取配置
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.Configure<BookOptions>(Configuration.GetSection(BookOptions.Book));
}
}
手动绑定
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
var bookOptions1 = new BookOptions();
Configuration.GetSection(BookOptions.Book).Bind(bookOptions1);
}
}
通过强类型注入来获取到配置对象
通过Options接口,我们可以读取依赖注入容器中的Options。常用的有三个接口:
IOptions<TOptions>
IOptionsSnapshot<TOptions>
IOptionsMonitor<TOptions>
IOptions(UnnameOptionsManager)
- 该接口对象实例生命周期为 Singleton,因此能够将该接口注入到任何生命周期的服务中
- 当该接口被实例化后,其中的选项值将永远保持不变,即使后续修改了与选项进行绑定的配置,也永远读取不到修改后的配置值
- 不支持命名选项(Nam