问题

如何在 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. 201521123093 java 第九周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己 ...

  2. 201521123001《Java程序设计》第11周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...

  3. Linux SDK之uClinux、Broadcom、Atheros、Realtek、Ralink、Marvell、Intel

    接触的Linux SDK越来越多,整理整理,分享分享,不求系统全面,对您有帮助便足矣 文中大部分是与AP/Router SoC解决方案(单芯片WIFI 路由器解决方案)相关的Linux SDK SDK ...

  4. PHP fwrite 函数:将字符串写入文件(追加与换行)(转)

    PHP fwrite() fwrite() 函数用于向文件写入字符串,成功返回写入的字符数,否则返回 FALSE . 语法: int fwrite( resource handle, string s ...

  5. PowerBI开发 第五篇:关系的设计

    PowerBI 使用 内存的列式数据库 VertiPaq,用于对已发布的数据集进行数据压缩和快速处理,能够使PowerBI报表执行脱机访问,面向列的处理,高度优化对1:N关系的处理性能.PowerBI ...

  6. python实例编写(3)--对话框,多窗口,下拉框,上传文件

    一.对话框: 例:点击百度的登录,弹出的小窗口 #coding=utf-8 from selenium import webdriver from time import sleep dr=webdr ...

  7. Ant-打增量包

    如何打增量包具体用法见如下百度网盘的文档. http://pan.baidu.com/s/1gd5pAp1 1, ant 打源码增量包 build_incremental_src.xml 内容如下: ...

  8. java乱码问题处理

    java乱码问题处理 java乱码出现的问题有很多,这里主要解释tomcat,jsp,html,http(get,post请求乱码处理).常见的问题可能是tomcat,http请求乱码问题,对于jsp ...

  9. [原创]MinHook测试与分析(x64下 E9,EB,CALL指令测试,且逆推测试微软热补丁)

    依稀记得第一次接触Hook的概念是在周伟民先生的书中-><<多任务下的数据结构与算法>>,当时觉得Hook很奇妙,有机会要学习到,正好近段日子找来了MiniHook,就一 ...

  10. GCD之死锁体会

    1.先看下几句代码 1 2 3 4 5 6 7 dispatch_queue_t serialqueue=dispatch_queue_create("serialqueue", ...