在.Net core中,微软放弃了笨重基于XML的.Config配置文件(好吧,像我这种咸鱼早都忘了如何自己写一个Section了)。

现在主推新的高度可扩展的配置文件(参见此处

对于新的配置系统,既可以通过IConfigurationSection.Value手工一个个获取配置项的值(神烦无比,别问我怎么知道的),也可以通过选择模式(options pattern)通过POCO(Plain Old CLR Object)类读取配置(参见如下代码片段:)

//配置POJO如下:
/*
public class FooConfig
{
public string Name { get; set; }
}
*/
//加载配置
var configBuilder = new ConfigurationBuilder();
configBuilder.SetBasePath(GetConfigDir());
configBuilder.AddJsonFile("config.json");
var configuration = configBuilder.Build(); //初始化默认DI容器
var services = new ServiceCollection();
services.AddOptions();
services.Configure<FooConfig>(configuration);//从配置文件读取FooConfig
var serviceProvider = services.BuildServiceProvider(); //获取FooConfig实例
var fooConfigOptions = serviceProvider.GetService<IOptions<FooConfig>>();
var fooConfig = fooConfigOptions.Value;
var name=fooConfig.Name;

看上去一切都好,直到当FooConfig中增加了一个IEnumerable<string>类型的属性,用来读取列表时:

public class FooConfig
{
public string Name { get; set; }
public IEnumerable<string> ValueList { get; set; }
}

跳出一个明晃晃的InvalidOperationException。说是不支持接口类型。

那么问题来了,Microsoft.Extensions.Options究竟支持什么样的配置类?

由于现今.Net core的文档少的可怜,这个问题就只有自己翻代码求解了。

首先看这段代码:

services.Configure<FooConfig>(configuration);//从配置文件读取FooConfig

似乎,一切秘密就在这个Configure扩展方法中?

首先查看Configure扩展方法的源码,我们又被带到了ConfigureFromConfigurationOptions类上。那么,这个类是如何读取配置的呢?

细节请自行查看,总结下,就是调用了Microsoft.Extensions.Configuration.ConfigurationBinder.Bind方法以绑定配置到配置类实例上(此处应有源码)。

细读代码,总结如下:

  1. 如果配置类中某个属性无对应配置,则不予处理(此时违反以下任何规则都没事,反正不处理)

  2. 配置类中所有属性的类型必须为IConfigurationSection或实际类型,不能为其他接口类型(interface)或抽象类(abstract clas)

  3. 如果配置类中某个属性无公共Get方法,忽略之

  4. 如果配置类中某个属性无公共Set方法,且属性无值(Get方法不返回值),则忽略之(这条太细致了吧……因为属性值本身还可能可以绑定配置)

  5. 对于配置的叶子节点(就是IConfigurationSection.Value有值的那些节点),则通过TypeDescriptor.GetConverter(type).ConvertFromInvariantString(value)转换字段(Nullable字段特殊处理,故而只要其基础类型支持转换就行)

  6. 对于非配置叶子节点的属性,支持以下集合类型:一维数组(最普通的array)、实现了ICollection<T>的集合、实现了IDictionary<TKey,TValue>的集合(TKey必须为string)、能够创建实例的类(都说了接口和抽象类不支持了嘛)

其实,如果不想使用IOptions,还可以直接Bind嘛:

var fooConfig=new FooConfig();
ConfigurationBinder.Bind(configuration,fooConfig);

Microsoft.Extensions.Options支持什么样的配置类?的更多相关文章

  1. 乘风破浪,遇见最佳跨平台跨终端框架.Net Core/.Net生态 - 官方扩展集锦(Microsoft.Extensions on Nuget)

    什么是Microsoft.Extensions .NET Platform Extensions是一套.Net官方的API集合,提供了一些常用的编程模式和实用工具,例如依赖项注入.日志记录.缓存.Ho ...

  2. 使用 Microsoft.Extensions.DependencyInjection 进行依赖注入

    没有 Autofac DryIoc Grace LightInject Lamar Stashbox Unity Ninject 的日子,才是好日子~~~~~~~~~~ Using .NET Core ...

  3. DotNetCore跨平台~一起聊聊Microsoft.Extensions.DependencyInjection

    写这篇文章的心情:激动 Microsoft.Extensions.DependencyInjection在github上同样是开源的,它在dotnetcore里被广泛的使用,比起之前的autofac, ...

  4. Asp.Net Core 2.0 项目实战(9) 日志记录,基于Nlog或Microsoft.Extensions.Logging的实现及调用实例

    本文目录 1. Net下日志记录 2. NLog的使用     2.1 添加nuget引用NLog.Web.AspNetCore     2.2 配置文件设置     2.3 依赖配置及调用     ...

  5. .NET Core采用的全新配置系统[5]: 聊聊默认支持的各种配置源[内存变量,环境变量和命令行参数]

    较之传统通过App.config和Web.config这两个XML文件承载的配置系统,.NET Core采用的这个全新的配置模型的最大一个优势就是针对多种不同配置源的支持.我们可以将内存变量.命令行参 ...

  6. .NET Core采用的全新配置系统[3]: “Options模式”下的配置是如何绑定为Options对象

    配置的原子结构就是单纯的键值对,并且键和值都是字符串,但是在真正的项目开发中我们一般不会单纯地以键值对的形式来使用配置.值得推荐的做法就是采用<.NET Core采用的全新配置系统[1]: 读取 ...

  7. “Options模式”下的配置是如何绑定为Options对象

    “Options模式”下的配置是如何绑定为Options对象 配置的原子结构就是单纯的键值对,并且键和值都是字符串,但是在真正的项目开发中我们一般不会单纯地以键值对的形式来使用配置.值得推荐的做法就是 ...

  8. asp.net core 2.0 Microsoft.Extensions.Logging 文本文件日志扩展

    asp.net core微软官方为日志提供了原生支持,有如下实现 Console Debug EventLog AzureAppServices TraceSource EventSource 并且在 ...

  9. Microsoft.Extensions.DependencyInjection不同版本导致EF出现内存泄露。

    我的代码里将IServiceProvider放入ServiceLocator中遇到的问题. 注:以下所有例子都是Console里的结论,AspNetCore里不管怎么玩都没有问题,有其他帖子测试出在A ...

随机推荐

  1. zedboard如何从PL端控制DDR读写(四)

    PS-PL之间的AXI 接口分为三种:• 通用 AXI(General Purpose AXI) — 一条 32 位数据总线,适合 PL 和 PS 之间的中低速通信.接口是透传的不带缓冲.总共有四个通 ...

  2. nginx的gzip选项和expire过期时间记录

    最近,参加了公司的组织的一个公开课,收获还是挺多的,下面来总结接一下: 一. 使用nginx来进行网页内容的压缩编码与传输速度的优化: 先来观察一下news.sina.com.cn在请求和传输的时候发 ...

  3. html如何绑定radio控件和label控件

    只要指定label的"for"属性到radio的id就行,或者用label标签包围住radio. 第一种方式: <input type="radio" i ...

  4. tdd 和 make file,以及cygwin

    等我把这本书看完,好好总结一下. 还要把以前的博客文字整理一下

  5. python之路-Day1

    Python 是一门什么样的语言? python是一门动态解释性的强类型定义语言 动态语言:动态类型语言是指在运行期间才去做数据类型检查的语言,也就是说,在用动态类型的语言编程时,永远也不用给任何变量 ...

  6. 8.Mybatis的延迟加载

    在Mybatis中的延迟加载只有resultMap可以实现,ResultMap 可以实现高级映射(association,collection可以实现一对1和一对多的映射),他们具有延迟加载的功能,r ...

  7. webform内置对象

    1.Response和Request地址栏数据拼接 QueryString 优点:简单好用:速度快:不消耗服务器内存. 缺点:只能传字符串:保密性差(调转页面后在地址栏显示):长度有限.响应请求对象 ...

  8. webform页面传值和删除修改

    一.webform跨页面传值1.内置对象地址栏数据拼接 QueryString 优点:简单好用:速度快:不消耗服务器内存. 缺点:只能传字符串:保密性差(调转页面后在地址栏显示):长度有限.响应请求对 ...

  9. java的四种取整方法

    java 中取整操作提供了四种方法:分别是: public static double ceil(double a)//向上取整  public static double floor(double ...

  10. shell中单引号和双引号

    在shell中声明变量后直接使用: #!/bin/bash na=zhagnsan ag=11 echo '$na is $ag years old' 输出:$na is $ag years old ...