问题

如何在 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. combox

    通过combox控件本身的item添加了选项后,该控件在启动后SelectedIndex默认值是-1,所以最好是在窗体加载的时候初始化城SelectedIndex=0 另外如果是窗体加载时item从数 ...

  2. 停止运行ExecutorService中的线程

    while(true){ try { sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch bloc ...

  3. UITextField最大字符数和最大字节数的限制

    UITextView,UITextfield中有很多坑,网上的方法也很多,但是用过之后暂时没有发现一个好用.这里我给大家几组测试用例可以一试,为啥不好用. 限制10个字节,输入2个Emoj之后是8个字 ...

  4. Hadoop之Hive(2)--配置Hive Metastore

    Hive metastore服务以关系性数据库的方式存储Hive tables和partitions的metadata,并且提供给客户端访问这些数据的metastore service的API.下面介 ...

  5. 温故知新---重读C#InDepth(二)

    一本好书,或是一本比较有深度的书,就是每次研读的时候都会有新的发现. 好吧,我承认每次读的时候都有泛泛而过的嫌疑~~ 这几年一直专注于C#客户端的开发,逐步从迷迷糊糊,到一知半解,再到自以为是,最后沉 ...

  6. CodeForces 361B Levko and Permutation

    题意:有n个数,这些数的范围是[1,n],并且每个数都是不相同的.你需要构造一个排列,使得这个排列上的数与它所在位置的序号的最大公约数满足 > 1,并且这些数的个数恰好满足k个,输出这样的一个排 ...

  7. hdoj 5112 A Curious Matt

    A Curious Matt Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) ...

  8. 3Sum Smaller 解答

    Question Given an array of n integers nums and a target, find the number of index triplets i, j, k w ...

  9. hust1010 kmp

    There is a string A. The length of A is less than 1,000,000. I rewrite it again and again. Then I go ...

  10. evak购物车--课程设计(201521123037邱晓娴)

    1. 团队课程设计博客链接 团队博客 2. 个人负责模块或任务说明 1.Java (1)编写用户类Users (2)编写DBConnection类,连接数据库 (3)编写GoodsDAO类,从数据库中 ...