问题

如何在 ASP.NET Core 2.0 应用程序中读取全局配置项?

答案

首先新建一个空项目,并添加两个配置文件:

1. appsettings.json

{
"Section1": {
"SettingA": "ValueA",
"SettingB": "ValueB"
},
"Section2": {
"SettingC": "ValueC"
}
}

2. appsettings.Development.json

{
"Section1": {
"SettingA": "Dev_ValueA"
},
"Section2": {
"SettingC": "Dev_ValueC"
}
}

Visual Studio会自动识别两者的关系,并在解决方案层次结构中展示如下:

然后创建相应的POCO类,分别对应于几个配置节点:

public class AppSettings
{
public AppSettingsSection1 Section1 { get; set; }
public AppSettingsSection2 Section2 { get; set; }
} public class AppSettingsSection1
{
public string SettingA { get; set; }
public string SettingB { get; set; }
} public class AppSettingsSection2
{
public string SettingC { get; set; }
}

在Startup.cs文件中,创建接收 IConfiguration 的构造函数:

public static IConfiguration Configuration { get; private set;}

public Startup(IConfiguration config)
{
Configuration = config;
}

然后在 ConfigureServices() 方法中添加Options服务,并设置依赖项:

public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<AppSettings>(Configuration);
}

最后,将配置项作为IOptions接口注入中间件的构造函数,其中泛型类型T就是我们刚才定义的POCO类:

public class HelloWorldMiddleware
{
private readonly RequestDelegate _next;
private readonly AppSettings _settings; public HelloWorldMiddleware(RequestDelegate next, IOptions<AppSettings> options)
{
_next = next;
_settings = options.Value;
} public async Task Invoke(HttpContext context)
{
var jsonSettings = JsonConvert.SerializeObject(_settings, Formatting.Indented);
await context.Response.WriteAsync(jsonSettings);
}
} public static class UseHelloWorldInClassExtensions
{
public static IApplicationBuilder UseHelloWorld(this IApplicationBuilder app)
{
return app.UseMiddleware<HelloWorldMiddleware>();
}
}

在Startup.cs的 Configure() 方法中,将此中间件注入到请求管道中:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHelloWorld();
}

运行,此时页面显示:

讨论

ASP.NET Core 拥有一个简单的机制来从各种数据源(比如JSON文件,环境变量,甚至是自定义数据源)中读取应用程序设置。然后通过依赖注入,方便的使用这些配置项。

尽管这一切看起来很魔幻(我们的设置究竟是如何加载的!),ASP.NET Core 2.0隐藏了从数据源中读取配置项的细节,这些内容本应该存在于Program.cs文件中WebHost的CreateDefaultBuilder()方法中。IConfiguration随后被添加到服务容器中,并在应用程序的其他部分保持可用,我们使用Startup中的此接口来添加配置项。为了观察这个过程,请将Program.cs文件中的BuildWebHost()方法替换为如下内容,得到的结果是一样的:

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureAppConfiguration((context, builder) =>
{
var env = context.HostingEnvironment; builder.AddJsonFile("appsettings.json",
optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json",
optional: true, reloadOnChange: true); if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(
new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
builder.AddUserSecrets(appAssembly, optional: true);
}
} builder.AddEnvironmentVariables(); if (args != null)
{
builder.AddCommandLine(args);
}
})
.Build();

在上面的解决方案中,我们提供了两个JSON文件数据源。需要记着的一点是,这些文件按照顺序被依次读取,后面的数据源会覆盖前面的数据源。你也可以在上面的运行结果中注意到,SettingB配置项来自于第一个配置文件,而其他两个配置项都来自于第二个配置文件。

注意:Startup.cs中的IConfiguration实例拥有public static修饰符,因此可以在整个应用程序期间使用此实例:

var valueA = Config["Section1:SettingA"];

然而,更好的办法是将配置项读入一个类型化的POCO类,并将其作为依赖项注入中间件或者控制器。上面的示例正好展示了这个模式。

你也可以为不同的配置节定义不同的POCO类,并使用IConfiguration的GetSection()方法来读取。

====start by sanshi=========================

下面我们简单扩展之前的示例,来读取不同的配置节:

public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<AppSettings>(Configuration);
services.Configure<AppSettingsSection1>(Configuration.GetSection("Section1"));
}

更新中间件代码,此时向中间件的构造函数注入两个依赖项:

public class HelloWorldMiddleware
{
private readonly RequestDelegate _next;
private readonly AppSettings _settings;
private readonly AppSettingsSection1 _settingsSection1; public HelloWorldMiddleware(RequestDelegate next, IOptions<AppSettings> options, IOptions<AppSettingsSection1> optionsSection1)
{
_next = next;
_settings = options.Value;
_settingsSection1 = optionsSection1.Value;
} public async Task Invoke(HttpContext context)
{
var jsonSettings = JsonConvert.SerializeObject(_settings, Formatting.Indented);
var jsonSettingsSection1 = JsonConvert.SerializeObject(_settingsSection1, Formatting.Indented);
await context.Response.WriteAsync("AppSettings:\n" + jsonSettings + "\n\nAppSettings - Section1:\n" + jsonSettingsSection1);
}
}

运行,此时页面显示:

====end by sanshi=========================

当然,我们也可以手工设置配置项的值,通过使用IServiceCollection.Configure的重载方法并接收强类型的lambda表达式:

====start by sanshi=========================

修改ConfigurationServices()方法,手工设置配置项:

public void ConfigureServices(IServiceCollection services)
{
services.AddOptions(); services.Configure<AppSettings>(options =>
{
options.Section1 = new AppSettingsSection1();
options.Section1.SettingA = "SettingA Value";
options.Section1.SettingB = "SettingB Value";
});
}

运行,此时页面效果:

====end by sanshi=========================

源代码下载

原文:https://tahirnaushad.com/2017/08/15/asp-net-core-configuration/

[译]ASP.NET Core 2.0 全局配置项的更多相关文章

  1. [译]ASP.NET Core 2.0 机密配置项

    问题 如何在ASP.NET Core 2.0中保存机密配置项(不用将其暴露给源代码管理器)? 答案 创建一个ASP.NET Core 2.0空项目,在项目节点上点击右键,并点击菜单项 - 管理用户机密 ...

  2. [译]ASP.NET Core 2.0 系列文章目录

    基础篇 [译]ASP.NET Core 2.0 中间件 [译]ASP.NET Core 2.0 带初始参数的中间件 [译]ASP.NET Core 2.0 依赖注入 [译]ASP.NET Core 2 ...

  3. [译]ASP.NET Core 2.0 中间件

    问题 如何创建一个最简单的ASP.NET Core中间件? 答案 使用VS创建一个ASP.NET Core 2.0的空项目,注意Startup.cs中的Configure()方法: public vo ...

  4. [译]ASP.NET Core 2.0 带初始参数的中间件

    问题 如何在ASP.NET Core 2.0向中间件传入初始参数? 答案 在一个空项目中,创建一个POCO(Plain Old CLR Object)来保存中间件所需的参数: public class ...

  5. [译]ASP.NET Core 2.0 会话状态

    问题 如何在ASP.NET Core 2.0中存储会话状态? 答案 创建一个空项目,修改Startup类的ConfigureServices()方法,添加会话状态服务和它后台的存储服务: public ...

  6. [译]ASP.NET Core 2.0 本地文件操作

    问题 如何在ASP.NET Core 2.0中受限地访问本地目录和文件信息? 答案 新建一个空项目,修改Startup类,添加访问本地文件所需的服务: public void ConfigureSer ...

  7. [译]ASP.NET Core 2.0 网址重定向

    问题 如何在ASP.NET Core 2.0中实现网址重定向? 答案 新建一个空项目,在Startup.cs文件中,配置RewriteOptions参数并添加网址重定向中间件(UseRewriter) ...

  8. [译]ASP.NET Core 2.0 路由引擎

    问题 ASP.NET Core 2.0的路由引擎是如何工作的? 答案 创建一个空项目,为Startup类添加MVC服务和请求中间件: public void ConfigureServices(ISe ...

  9. [译]ASP.NET Core 2.0 路由引擎之网址生成

    问题 如何在ASP.NET Core 2.0中由路由引擎来生成网址? 答案 新建一个空项目,修改Startup.cs文件,添加MVC服务和中间件: public void ConfigureServi ...

随机推荐

  1. 201521123079《Java程序设计》第2周学习总结

    1. 本周学习总结 学会String类和StringBuilder类的一些用法. 学会使用码云管理代码,会将码云上的代码和本地仓库关联 2. 书面作业 Q1.使用Eclipse关联jdk源代码,并查看 ...

  2. Geronimo tomcat: 在 Apache Geronimo 插件体系中将 Apache Tomcat 这个优秀的 Web 容器整合至其中

    Apache Geronimo 灵活的插件体系将 Tomcat, OpenJPA, OpenEJB, ActiveMQ 等第三方组件集成至其中.本文从多角度介绍了在 Apache Geronimo 中 ...

  3. Java多线程高并发学习笔记(二)——深入理解ReentrantLock与Condition

    锁的概念 从jdk发行1.5版本之后,在原来synchronize的基础上,增加了重入锁ReentrantLock. 本文就不介绍synchronize了,有兴趣的同学可以去了解一下,本文重点介绍Re ...

  4. MinHook测试与分析(x86下 E8,E9,EB,CALL指令测试,且逆推测试微软热补丁)

    依稀记得第一次接触Hook的概念是在周伟民先生的书中-><<多任务下的数据结构与算法>>,当时觉得Hook的本质就是拦截,就算到现在也是如此认为. 本篇文章是在x86下测 ...

  5. SpringMVC第二篇【过滤编码器、注解开发、requestMapping、业务方法与传统参数】

    SpringMVC过滤编码器 在SpringMVC的控制器中,如果没有对编码进行任何的操作,那么获取到的中文数据是乱码! 即使我们在handle()方法中,使用request对象设置编码也不行!原因也 ...

  6. 【二】刚学Python的几道简单练习题

    python交友娱乐会所:613176398 1.使用while循环输入 1 2 3 4 5 6     8 9 10 2.求1-100的所有数的和 3.输出 1-100 内的所有奇数 4.输出 1- ...

  7. [实战演练]python3使用requests模块爬取页面内容

    本文摘要: 1.安装pip 2.安装requests模块 3.安装beautifulsoup4 4.requests模块浅析 + 发送请求 + 传递URL参数 + 响应内容 + 获取网页编码 + 获取 ...

  8. 为什么要用深度学习来做个性化推荐 CTR 预估

    欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:苏博览 深度学习应该这一两年计算机圈子里最热的一个词了.基于深度学习,工程师们在图像,语音,NLP等领域都取得了令人振奋的进展.而深 ...

  9. Class.getResource和ClassLoader.getResource的区别分析

    原文:http://swiftlet.net/archives/868 在Java中获取资源的时候,经常用到Class.getResource和ClassLoader.getResource,本文给大 ...

  10. ApplicationContextAware

    1.实现了ApplicationContextAware接口,在Bean的实例化时会自动调用setApplicationContext()方法! 2.通过调用静态方法getBean即可获取 sprin ...