在.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. 使用celery的backend异步获取结果

    惯例先贴出相关参考的文档: http://docs.celeryproject.org/en/stable/getting-started/next-steps.html http://docs.ce ...

  2. 浅谈OpenGL变换矩阵

    OpenGL中使用的矩阵全为列向量为主的矩阵. 参考OpenGL变换网站为  http://www.songho.ca/opengl/gl_transform.html 1.什么是GL_MODELVI ...

  3. http的header参数有关

    1.读文件 a.如果经过php处理:变成mime:text/html,在浏览器可以打开.否则是下载 b.phpui如果加上参数resid=01,那么返回的数据的Content-Type:applica ...

  4. php加密解密0x数组

    <?php //加密字符串 $str='hello world'; $arr=str_split($str); $arr1=array(); foreach($arr as $v){ $ordv ...

  5. java 常见关键字的使用

    Super 关键字:指向父类对象的引用空间. 作用:1.当子类和父类存在同名的成员变量时,可以通过super来调用父类的成员变量. 2.super可以用来调用父类的构造方法. Instanceof 关 ...

  6. SQL SERVER 2008 字段值合并

    /** * 通过 FOR XML PATH 语句,可以将字段的值进行合并. **/ CREATE TABLE tb_child ( name ), hobby ) ) go INSERT INTO t ...

  7. Queue、进程、线程、协程

    参考博客地址 http://www.cnblogs.com/alex3714/articles/5230609.html 1.python GIL全局解释器锁 python调用的操作系统的原生线程,当 ...

  8. socket笔记

    参考: http://www.cnblogs.com/dolphinX/p/3460545.html http://www.cnblogs.com/wei2yi/archive/2011/03/23/ ...

  9. nullcon HackIM 2016 -- Programming Question 2

    Your simple good Deeds can save you but your GREED can kill you. This has happened before. This gree ...

  10. access数据库连接问题

    使用Visual Studio连接access数据库(数据库后缀.accdb)时连接不上(access数据库提示未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序)解决办 ...