使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(七)-- 结构化配置
本篇将记录.Net Core里颇有特色的结构化配置的使用方法。
相比较之前通过Web.Config或者App.Config配置文件里使用xml节点定义配置内容的方式,.Net Core在配置系统上发生了很大的变化,具有了配置源多样化、更加轻量、扩展性更好的特点。
第一部分、基于键值对的配置
如果要使用结构化配置,需要先引用 "Microsoft.Extensions.Configuration": "1.0.0" nuget包。下面通过一个.Net Core控制台程序演示
一、单层结构的配置
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Memory;
using System;
using System.Collections.Generic; namespace DiApplicationTest
{
public class Program
{
public static void Main(string[] args)
{
IDictionary<string, string> source = new Dictionary<string, string>()
{
["Ele1"] = "value1",
["Ele2"] = "value2"
}; IConfiguration config = new ConfigurationBuilder().Add(new MemoryConfigurationSource() { InitialData = source }).Build();
Console.WriteLine($"Ele1: {config["Ele1"]}");
Console.WriteLine($"Ele2: {config["Ele2"]}"); Console.ReadLine();
}
}
}
启动调试,查看cmd窗口输出内容

上面的例子里,将一个字典作为配置源读入到config配置对象里,通过键可以读取到对应的值。
二、多层结构的配置
在大多数情况下,项目里的配置都是多层结构的,也可以称为是结构化的。在上面的例子的基础上稍加修改,实现结构化的配置读取。
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Memory;
using System;
using System.Collections.Generic; namespace DiApplicationTest
{
public class Program
{
public static void Main(string[] args)
{
IDictionary<string, string> source = new Dictionary<string, string>()
{
["Ele1"] = "value1",
["Ele2:Sub1"] = "value2.1",
["Ele2:Sub2"] = "value2.2"
}; IConfiguration config = new ConfigurationBuilder().Add(new MemoryConfigurationSource() { InitialData = source }).Build();
Console.WriteLine($"Ele1: {config["Ele1"]}");
Console.WriteLine($"Ele2.Sub1: {config.GetSection("Ele2")["Sub1"]}");
Console.WriteLine($"Ele2.Sub2: {config.GetSection("Ele2")["Sub2"]}"); Console.ReadLine();
}
}
}
启动调试,查看cmd窗口输出内容

在这个例子里,字典内容描述了一个具有两层结构的配置,第一层有Ele1和Ele2两个节点,分别对应一个字符内容和一个复合内容,第二层有Sub1和Sub2两个节点,同时挂在Ele2节点下,组成了一个复合结构。
注意看字典项里的Key,因为字典里的数据是扁平化的,为了能清晰描述节点之间的上下层关系,需要通过“:”符号来标识。
config对象通过GetSection方法来获取当前节点的某个下级节点内容。
第二部分、其他配置来源
除了上面例子里展示的配置源来自内存内容,也可以来自Xml文件、JSON文件或者数据库等。因为在.Net Core里使用JSON文件描述配置内容很常见,下面就展示如何读取JSON配置文件。
先添加如下两个nuget包,支持从json文件读取内容
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
添加 appsettings.json 文件
{
"Ele1": "value1",
"Ele2": {
"Sub1": "value2.1",
"Sub2": "value2.2"
}
}
修改Main函数内容
using Microsoft.Extensions.Configuration;
using System;
using System.IO; namespace DiApplicationTest
{
public class Program
{
public static void Main(string[] args)
{
IConfigurationBuilder builder = new ConfigurationBuilder();
builder.SetBasePath(Directory.GetCurrentDirectory());
builder.AddJsonFile("appsettings.json"); IConfiguration config = builder.Build();
Console.WriteLine($"Ele1: {config["Ele1"]}");
Console.WriteLine($"Ele2.Sub1: {config.GetSection("Ele2")["Sub1"]}");
Console.WriteLine($"Ele2.Sub2: {config.GetSection("Ele2")["Sub2"]}"); Console.ReadLine();
}
}
}
启动调试,查看cmd窗口输入内容,与上面的例子内容一致。
这个例子将原来在字典里的内容转换成Json格式化的内容存储在持久化文件里。通过指定配置源,同样可以读取内容。
第三部分、Options对象映射
当配置文件内容较多时,通过config的Key获取对应的配置项的值变得比较繁琐。.Net Core的配置系统采用了一种叫“Options Pattern”的模式使配置内容与有着对应结构的对象进行映射,这种对象就叫做Options对象。
下面将简单演示一下这种映射方式。
首先添加如下nuget包引用,使用此模式的相关接口和类都在这个包里。同时还需要引入DI容器。
"Microsoft.Extensions.DependencyInjection": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
添加两个具有层级结构的Options类
public class ConfigOptions
{
public string Ele1 { get; set; }
public SubConfigOptions Ele2 { get; set; }
} public class SubConfigOptions
{
public string Sub1 { get; set; }
public string Sub2 { get; set; }
}
修改Main函数内容
public static void Main(string[] args)
{
// 创建DI容器,注册Options Pattern服务
IServiceCollection services = new ServiceCollection();
services.AddOptions(); // 读取配置文件
IConfigurationBuilder builder = new ConfigurationBuilder();
builder.SetBasePath(Directory.GetCurrentDirectory());
builder.AddJsonFile("appsettings.json");
IConfiguration config = builder.Build(); // 通过注册的服务获取最终映射的配置对象
IServiceProvider serviceProvider = services.Configure<ConfigOptions>(config).BuildServiceProvider();
ConfigOptions options = serviceProvider.GetService<IOptions<ConfigOptions>>().Value; Console.WriteLine($"Ele1: {options.Ele1}");
Console.WriteLine($"Ele2.Sub1: {options.Ele2.Sub1}");
Console.WriteLine($"Ele2.Sub2: {options.Ele2.Sub2}"); Console.ReadLine();
}
启动调试,查看cmd窗口输入内容,与上面的例子内容一致。
在定义Options对象结构时,对象内的属性名称要与对应层级的配置Key的值保持一致,层级关系也要与配置内容的层级结构保持一致。
通过调用 services.AddOptions() 方法注册Options Pattern服务。将配置内容注册到容器里,来获取对应的服务Provider对象。通过调用GetService方法获得对应的真实服务对象,即带有事先定义的Options类型的泛型接口IOptions,接口的Value值就是配置内容映射的Options对象。
第四部分、Asp.Net Core里的配置管理
在这个系列之前使用的例子里添加配置管理相关的功能,来修改初始化日志级别的代码,同时添加一些自定义配置。
先添加配置相关的nuget包
"Microsoft.Extensions.Configuration": "1.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0"
添加appsettings.json文件
{
// 日志配置
"Logging": {
"LogLevel": {
"Microsoft": "Warning"
}
},
// 自定义配置
"CfgContent": {
"Ele1": "value1",
"Ele2": {
"Sub1": "value2.1",
"Sub2": "value2.2"
}
}
}
添加上个例子里的 ConfigOptions.cs、SubConfigOptions.cs 类,修改 Startup.cs 的内容,添加配置相关代码
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; namespace WebApiFrame
{
public class Startup
{
public IConfiguration Configuration { get; } public Startup()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json"); Configuration = builder.Build();
} public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<ConfigOptions>(Configuration.GetSection("CfgContent")); // 注入MVC框架
services.AddMvc();
} public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
// 添加日志支持
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug(); // 添加NLog日志支持
//loggerFactory.AddNLog(); // 添加MVC中间件
app.UseMvc();
}
}
}
修改 DemoController.cs 内容
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; namespace WebApiFrame
{
[Route("[controller]")]
public class DemoController : Controller
{
private ConfigOptions _cfgContent { get; } public DemoController(IOptions<ConfigOptions> options)
{
_cfgContent = options.Value;
} [HttpGet("index")]
public async Task Index()
{
HttpContext.Response.ContentType = "text/html";
await HttpContext.Response.WriteAsync($"<span>Ele1: {_cfgContent.Ele1}</span><br />");
await HttpContext.Response.WriteAsync($"<span>Ele2.Sub1: {_cfgContent.Ele2.Sub1}</span><br />");
await HttpContext.Response.WriteAsync($"<span>Ele2.Sub2: {_cfgContent.Ele2.Sub2}</span><br />");
}
}
}
启动调试,访问地址 http://localhost:5000/demo/index ,页面显示配置内容

从这个例子里可以看到,读取 appsettings.json 配置文件内容并分成两部分,其中一部分配置Logging作为Logger的配置内容用于日志初始化,另外一部分CfgContent配置内容注册到DI容器,在控制器的构造函数里通过IOptions泛型类型的参数注入,这样控制器就可以读取配置文件的内容。
使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(七)-- 结构化配置的更多相关文章
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(一)-- 起步
本文记录了在Windows环境下安装Visual Studio Code开发工具..Net Core 1.0 SDK和开发一个简单的Web-Demo网站的全过程. 一.安装Visual Studio ...
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(八)-- 多环境开发
本篇将演示Asp.Net Core如何在多环境下进行开发适配. 在一个正规的开发流程里,软件开发部署将要经过三个阶段:开发.测试.上线,对应了三个环境:开发.测试.生产.在不同的环境里,需要编写不同的 ...
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(十)-- 发布(Windows)
本篇将在这个系列演示的例子上继续记录Asp.Net Core在Windows上发布的过程. Asp.Net Core在Windows上可以采用两种运行方式.一种是自托管运行,另一种是发布到IIS托管运 ...
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(九)-- 单元测试
本篇将结合这个系列的例子的基础上演示在Asp.Net Core里如何使用XUnit结合Moq进行单元测试,同时对整个项目进行集成测试. 第一部分.XUnit 修改 Project.json 文件内容, ...
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(三)-- Logger
本篇是在上一篇的基础上添加日志功能,并记录NLog在Asp.Net Core里的使用方法. 第一部分:默认Logger支持 一.project.json添加日志包引用,并在cmd窗口使用 dotnet ...
- [转]使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(三)-- Logger
本文转自:https://www.cnblogs.com/niklai/p/5662094.html 本篇是在上一篇的基础上添加日志功能,并记录NLog在Asp.Net Core里的使用方法. 第一部 ...
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(六)-- 依赖注入
本篇将介绍Asp.Net Core中一个非常重要的特性:依赖注入,并展示其简单用法. 第一部分.概念介绍 Dependency Injection:又称依赖注入,简称DI.在以前的开发方式中,层与层之 ...
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(五)-- Filter
在上一篇里,介绍了中间件的相关内容和使用方法.本篇将介绍Asp.Net Core MVC框架的过滤器的相关内容和使用方法,并简单说明一下与中间件的区别. 第一部分.MVC框架内置过滤器 下图展示了As ...
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(四)-- Middleware
本文记录了Asp.Net管道模型和Asp.Net Core的Middleware模型的对比,并在上一篇的基础上增加Middleware功能支持. 在演示Middleware功能之前,先要了解一下Asp ...
随机推荐
- ruby-rails 环境搭建
https://ruby-china.org/wiki/install_ruby_guide
- [ActionScript 3.0] AS3调用百度天气预报查询API
接口说明 根据经纬度/城市名查询天气的结果 接口示例 http://api.map.baidu.com/telematics/v3/weather?location=成都&output=jso ...
- JAVA继承时this和super关键字
JAVA继承时this和super关键字 本文主要讨论在方法前使用this或super关键字时,编译器在什么地方查找对应的函数. 在子类中指定this关键字.首先在本类中查找,如果本类中找不到,再在父 ...
- SQL字符串分组聚合(分组后的数据查询后用逗号隔开)
)) , 'aa') , 'bb') , 'aaa') , 'bbb') , 'ccc') go , , '') from tb group by id
- Entity Framework6 访问MySQL
先用PM命令安装EF6,MySQL提供的EF实现新增.删除.修改是采用存储过程实现的 Install-Package EntityFramework 配置修改如下 <?xml version=& ...
- [SQL]SQL语言入门级教材_SQL数据操作基础(二)
SQL数据操作基础(初级) netnova 于 -- :: 加贴在 数据库探讨: 为了建立交互站点,你需要使用数据库来存储来自访问者的信息.例如,你要建立一个职业介绍服务的站点,你就需要存储诸如个人简 ...
- nyoj 91 阶乘之和
点击打开链接 阶乘之和 时间限制:3000 ms | 内存限制:65535 KB 难度: 描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2 ...
- cookie机制和session机制的原理和区别[转]
一.cookie机制和session机制的区别 具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案. 同时我们也看到,由于在服务器端保持状态的 ...
- junit适配器模式应用
适配器模式 定义: 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作: 构成: 目标抽象角色(Target):定义客户要用的特定领 ...
- Django中级篇之模板语言
模板 一.引用变量 模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户. {{ xxx }} 二.标签 用{% %} ...