《ASP.NET Core 6框架揭秘》实例演示[25]:配置与承载环境的应用

与服务注册一样,针对配置的设置同样可以采用三种不同的编程模式。第一种是利用WebApplicationBuilder的Host属性返回的IHostBuilder对象,它可以帮助我们设置面向宿主和应用的配置。IWebHostBuilder接口上面同样提供了一系列用来对配置进行设置的方法,我们可以将这些方法应用到WebApplicationBuilder的WebHost属性返回的IWebHostBuilder对象上。不过还是那句话,既然推荐使用Mininal API,最好还是采用最新的编程方式。[本文节选《ASP.NET Core 6框架揭秘》第15章]

[S1513]基于环境变量的配置初始化(源代码)
[S1514]以键值对形式读取和修改配置(源代码)
[S1515]注册配置源(利用IWebHostBuilder)(源代码)
[S1516]注册配置源(Minimal API)(源代码)
[S1517]默认的承载环境(源代码)
[S1518]通过配置定制承载环境(源代码)
[S1519]利用WebApplicationOptions定制承载环境(源代码)

[S1513]基于环境变量的配置初始化

应用启动的时候会将当前的环境变量作为配置源来创建承载最初配置数据的IConfiguration对象,但它只会选择名称以“ASPNETCORE_”为前缀的环境变量(通过静态类型Host的CreateDefaultBuilder方法创建的HostBuilder默认选择的是前缀为“DOTNET_”的环境变量)。在演示针对环境变量的初始化配置之前,需要先解决配置的消费问题,即如何获取配置数据。如下面的代码片段所示,我们设置两个环境变量,它们的名称分别为"ASPNETCORE_FOO"和"ASPNETCORE_BAR"。在调用WebApplication的CreateBuilder方法创建出WebApplicationBuilder对象之后,我们将它的Configuration属性提取出来。由调试断言可以看出这两个环境变量被成功转移到配置中了。代表承载应用的WebApplication构建出来后,其Configuration属性返回的IConfiguration对象上同样包含着相同的配置。

using System.Diagnostics;Environment.SetEnvironmentVariable("ASPNETCORE_FOO", "123");
Environment.SetEnvironmentVariable("ASPNETCORE_BAR", "456");var builder = WebApplication.CreateBuilder(args);
IConfiguration configuration = builder.Configuration;
Debug.Assert(configuration["foo"] == "123");
Debug.Assert(configuration["bar"] == "456");var app = builder.Build();
configuration = app.Configuration;
Debug.Assert(configuration["foo"] == "123");
Debug.Assert(configuration["bar"] == "456");

[S1514]以键值对形式读取和修改配置

我们知道IConfiguration对象是以字典的结构来存储配置数据的,我们可以利用该对象提供的索引以键值对的形式来读取和修改配置。在ASP.NET Core应用中,我们可以通过调用定义在IWebHostBuilder接口的GetSetting方法和UseSetting方法达到相同的目的。

public interface IWebHostBuilder
{string GetSetting(string key);IWebHostBuilder UseSetting(string key, string value);...
}

如下面的代码片段所示,我们可以通过利用WebApplicationBuilder的WebHost属性将对应的IWebHostBuilder对象提取出来,通过调用其GetSetting方法将以环境变量设置的配置提取出来。通过调用其UseSetting方法提供的键值对会保存到应用的配置中。配置最终的状态被固定下来后转移到了构建的WebApplication对象上。

using System.Diagnostics;var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseSetting("foo", "abc");
builder.WebHost.UseSetting("bar", "xyz");Debug.Assert(builder.WebHost.GetSetting("foo") == "abc");
Debug.Assert(builder.WebHost.GetSetting("bar") == "xyz");IConfiguration configuration = builder.Configuration;
Debug.Assert(configuration["foo"] == "abc");
Debug.Assert(configuration["bar"] == "xyz");var app = builder.Build();
configuration = app.Configuration;
Debug.Assert(configuration["foo"] == "abc");
Debug.Assert(configuration["bar"] == "xyz");

[S1515]注册配置源(利用IWebHostBuilder)

配置系统最大的特点是可以注册不同的配置源。针对配置源的注册同样可以利用三种编程方式来实现,第一种就是利用WebApplicationBuilder的Host属性返回的IHostBuilder对象,并调用其的ConfigureHostConfiguration和ConfigureAppConfiguration方法完成针对宿主和应用的配置,其中自然包含针对配置源的注册。IWebHostBuilder接口也提供如下这个等效的ConfigureAppConfiguration方法。如代码片段所示,该方法提供的参数是一个Action<WebHostBuilderContext, IConfigurationBuilder>委托,这意味着我们可以就承载上下文对配置做针对性设置。如果提供的设置与当前承载上下文无关,我们还可以调用另一个参数类型为Action<IConfigurationBuilder>的ConfigureAppConfiguration方法重载。

public interface IWebHostBuilder
{IWebHostBuilder ConfigureAppConfiguration(Action<WebHostBuilderContext, IConfigurationBuilder> configureDelegate);
}public static class WebHostBuilderExtensions
{public static IWebHostBuilder ConfigureAppConfiguration(this IWebHostBuilder hostBuilder, Action<IConfigurationBuilder> configureDelegate);
}

我们可以利用WebApplicationBuilder的WebHost属性返回对应的IWebHostBuilder对象,并采用如下的方式利用这个对象注册配置源。

using System.Diagnostics;var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureAppConfiguration(config => config.AddInMemoryCollection(new Dictionary<string, string>{["foo"] = "123",["bar"] = "456"}));
var app = builder.Build();
Debug.Assert(app.Configuration["foo"] == "123");
Debug.Assert(app.Configuration["bar"] == "456");

[S1516]注册配置源(Minimal API)

由于WebApplicationBuilder的Configuration属性返回的ConfigurationManager自身就是一个IConfigurationBuilder对象,所以最直接的方式就是按照如下的方式将配置源注册到它上面,这也是我们提供的编程方式。值得一提的是,如果调用WebApplication类型的CreateBuilder或者Create方法时传入了命令行参数,会自动添加针对命令行参数的配置源。

using System.Diagnostics;var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddInMemoryCollection(new Dictionary<string, string>
{["foo"] = "123",["bar"] = "456"
});
var app = builder.Build();
Debug.Assert(app.Configuration["foo"] == "123");
Debug.Assert(app.Configuration["bar"] == "456");

[S1517]默认的承载环境

如下面的代码片段所示,派生于IHostEnvironment接口的IWebHostEnvironment接口定义了WebRootPath和WebRootFileProvider属性,前者表示用于存放Web资源文件根目录的路径,后者则返回该路径对应的IFileProvider对象。如果我们希望外部可以采用HTTP请求的方式直接访问某个静态文件(如JavaScript、CSS和图片文件等),只需要将它存放于WebRootPath属性表示的目录之下即可。当前承载环境之间反映在WebApplicationBuilder类型如下所示的Environment属性中。代表承载应用的WebApplication类型同样具有这样一个属性。

public interface IWebHostEnvironment : IHostEnvironment
{string WebRootPath { get; set; }IFileProvider WebRootFileProvider { get; set; }
}public sealed class WebApplicationBuilder
{public IWebHostEnvironment Environment { get; }...
}public sealed class WebApplication
{public IWebHostEnvironment Environment { get; }...
}

我们简单介绍与承载环境相关的六个属性(包含定义在IHostEnvironment接口中的四个属性)是如何设置的。IHostEnvironment 接口的ApplicationName代表当前应用的名称,它的默认值为入口程序集的名称。EnvironmentName表示当前应用所处部署环境的名称,其中开发(Development)、预发(Staging)和产品(Production)是三种典型的部署环境。根据不同的目的可以将同一个应用部署到不同的环境中,在不同环境中部署的应用往往具有不同的设置。在默认情况下,环境的名称为“Production”。ASP.NET Core应用会将所有的内容文件存储在同一个目录下,这个目录的绝对路径通过IWebHostEnvironment接口的ContentRootPath属性来表示,而ContentRootFileProvider属性则返回针对这个目录的PhysicalFileProvider对象。部分内容文件可以直接作为Web资源(如JavaScript、CSS和图片等)供客户端以HTTP请求的方式获取,存放此种类型内容文件的绝对目录通过IWebHostEnvironment接口的WebRootPath属性来表示,而针对该目录的PhysicalFileProvider自然可以通过对应的WebRootFileProvider属性来获取。

在默认情况下,由ContentRootPath属性表示的内容文件的根目录就是当前工作目录。如果该目录下存在一个名为“wwwroot”的子目录,那么它将用来存放Web资源,WebRootPath属性将返回这个目录。如果这样的子目录不存在,那么WebRootPath属性会返回Null。针对这两个目录的默认设置体现在如下所示的代码片段中。

using System.Diagnostics;
using System.Reflection;var builder = WebApplication.CreateBuilder();
var environment = builder.Environment;Debug.Assert(Assembly.GetEntryAssembly()?.GetName().Name == environment.ApplicationName);
var currentDirectory = Directory.GetCurrentDirectory();Debug.Assert(Equals( environment.ContentRootPath,  currentDirectory));
Debug.Assert(Equals(environment.ContentRootPath, currentDirectory));var wwwRoot = Path.Combine(currentDirectory, "wwwroot");
if (Directory.Exists(wwwRoot))
{Debug.Assert(Equals(environment.WebRootPath, wwwRoot));
}
else
{Debug.Assert(environment.WebRootPath == null);
}static bool Equals(string path1, string path2) =>string.Equals(path1.Trim(Path.DirectorySeparatorChar), path2.Trim(Path.DirectorySeparatorChar),StringComparison.OrdinalIgnoreCase);

[S1518]通过配置定制承载环境

IWebHostEnvironment对象承载的与承载环境相关的属性(ApplicationName、EnvironmentName、ContentRootPath和WebRootPath)可以通过配置的方式进行定制,对应配置项的名称分别为“applicationName”、“environment”、“contentRoot”和“webroot”。静态类WebHostDefaults为它们定义了对应的属性。前三个配置项的名称同样以静态只读字段的形式定义在HostDefaults类型中。

public static class WebHostDefaults
{public static readonly string EnvironmentKey = "environment";public static readonly string ContentRootKey = "contentRoot";public static readonly string ApplicationKey = "applicationName";public static readonly string WebRootKey = "webroot";;
}public static class HostDefaults
{public static readonly string EnvironmentKey = "environment";public static readonly string ContentRootKey = "contentRoot";public static readonly string ApplicationKey = "applicationName";
}

由于应用初始化过程中的很多操作都与当前的承载环境有关,所以承载环境必须在启动应用最初的环境就被确定下来,并在整个应用生命周期内都不能改变。如果我们希望采用配置的方式来控制当前应用的承载环境,相应的设置必须在WebApplicationBuilder对象创建之前执行,在之后试图修改相关的配置都会抛出异常。按照这个原则,我们可以采用命令行参数的方式对承载环境进行设置。

var app = WebApplication.Create(args);
var environment = app.Environment;Console.WriteLine($"ApplicationName:{environment.ApplicationName}");
Console.WriteLine($"ContentRootPath:{environment.ContentRootPath}");
Console.WriteLine($"WebRootPath:{environment.WebRootPath}");
Console.WriteLine($"EnvironmentName:{environment.EnvironmentName}");

上面的演示程序利用命令行参数的方式控制承载环境的四个属性。如代码片段所示,我们将命令行参数传入WebApplication类型的Create方法创建了一个WebApplication对象,然后从中提取出代表承载环境的IWebHostEnvironment对象并将其携带信息输出到控制台上。我们命令行的方式启动该程序,并指定了与承载环境相关的四个参数。

c7767b8db10ab0cfd010a23f076274b9.png
图1 利用命令行参数定义承载环境

除了命令行参数,使用环境变量同样能达到相同的目的,应用的名称目前无法通过对应的配置进行设置。对于上面创建的这个演示程序,我们现在换一种方式启动它。如图2所示,在执行“dotnet run”命令启动程序之前,我们为承载环境的四个属性设置了对应的环境变量。从输出的结果可以看出,除了应用名称依然是入口程序集名称外,承载环境的其他三个属性与我们设置的环境变量是一致的。

5e1430736a7e4b0fb1c7f635b24a0ea0.png
图2 利用环境变量定义承载环境

[S1519]利用WebApplicationOptions定制承载环境

承载环境除了可以采用利用上面演示的两种方式进行设置外,我们也可以使用如下这个WebApplicationOptions配置选项。如代码片段所示,WebApplicationOptions定义了四个属性,分别代表命令行参数数组、环境名称、应用名称和内容根目录路径。WebApplicationBuilder具有如下这个参数类型为WebApplicationOptions的CreateBuilder方法。

public class WebApplicationOptions
{public string[] Args { get; set; }public string EnvironmentName { get; set; }public string ApplicationName { get; set; }public string ContentRootPath { get; set; }
}public sealed class WebApplication
{public static WebApplicationBuilder CreateBuilder(WebApplicationOptions options);...
}

如果利用WebApplicationOptions来对应用所在的承载环境进行设置,上面演示的程序可以改写成如下的形式。由于WebApplicationOptions并不包含WebRootPath对应的配置选项,如果程序运行后会发现承载环境的这个属性为空。由于IWebHostEnvironment服务提供的应用名称会被视为一个程序集名称,针对它的设置会影响类型的加载,所以我们基本上不会设置应用的名称。

var options = new WebApplicationOptions
{Args = args,ApplicationName = "MyApp",ContentRootPath = Path.Combine(Directory.GetCurrentDirectory(), "contents"),EnvironmentName = "staging"
};
var app = WebApplication.CreateBuilder(options).Build();
var environment = app.Environment;
Console.WriteLine($"ApplicationName:{environment.ApplicationName}");
Console.WriteLine($"ContentRootPath:{environment.ContentRootPath}");
Console.WriteLine($"WebRootPath:{environment.WebRootPath}");
Console.WriteLine($"EnvironmentName:{environment.EnvironmentName}");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/282875.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux日志出现大量kernel: NET: Registered protocol family 36

一台Linux服务器的系统错误日志出现大量的“ kernel: NET: Registered protocol family 36”错误信息&#xff0c;如下所示&#xff1a; Jul 2 05:27:45 xxxxxx kernel: NET: Registered protocol family 36Jul 2 05:27:45 xxxxxx kernel: NET: Unregistered protocol family…

node的模块机制

Node.js模块的实现 之前在网上查阅了许多介绍Node.js的文章&#xff0c;可惜对于Node.js的模块机制大都着墨不多。在后续介绍模块的使用之前&#xff0c;我认为有必要深入一下Node.js的模块机制。 CommonJS规范 早在Netscape诞生不久后&#xff0c;JavaScript就一直在探索本地编…

httpstat:一个检查网站性能的 curl 统计分析工具

httpstat&#xff1a;一个检查网站性能的 curl 统计分析工具httpstat 是一个 Python 脚本&#xff0c;它以美妙妥善的方式反映了 curl 统计分析&#xff0c;它是一个单一脚本&#xff0c;兼容 Python 3 &#xff0c;在用户的系统上不需要安装额外的软件(依赖)。作者&#xff1a…

关于面试中看到一些问题

最近公司在招聘.NET开发人员&#xff0c;面试了一些人&#xff0c;有一些感悟&#xff0c;分享出来&#xff0c;以供参考。面试的人员中&#xff0c;有一些是三五年的开发人员&#xff1b;也有几个是10年左右的技术负责人&#xff0c;不但自己架构过项目&#xff0c;还有带领导…

一个countDown在多线程调度下使用不当的分享

2019独角兽企业重金招聘Python工程师标准>>> 一个countDown在多线程调度下使用不当的分享 1. 诡异的数据抖动 在一个需求开发过程中&#xff0c;由于有多角色需要获取每个角色下的菜单&#xff1b;结果出现了单角色下拉去菜单没问题&#xff0c;多角色情况下只有一个…

linux脚本打印循环次数,shell脚本编程基础(3)——循环用法

本节索引&#xff1a;一、if、case条件判断二、for、while及until循环三、循环控制语句continue、break、shift及select菜单四、信号捕捉trap在前面的基础编程内容中&#xff0c;我们已经学习了shell脚本的顺序执行及选择执行&#xff0c;通过这两种方式&#xff0c;可以帮我们…

EF CORE 7 中的新功能:使用 ExecuteDelete 和 ExecuteUpdate 进行批量操作

原文链接&#xff1a;https://timdeschryver.dev/blog/new-in-entity-framework-7-bulk-operations-with-executedelete-and-executeupdate原文作者&#xff1a;tim_deschryver翻译&#xff1a;沙漠尽头的狼(谷歌翻译加持)Entity Framework 7 包括一些已被要求的流行功能&#…

java 简单json和对象相互转换

2019独角兽企业重金招聘Python工程师标准>>> package Fasterxml; import com.fasterxml.jackson.databind.ObjectMapper; import mode.User; import java.io.StringWriter; import java.util.ArrayList; import java.util.List;/*** maven...**<dependency>* …

畅想动画制作的乐趣

为什么要制作动画&#xff1f; 现在的营销活动&#xff0c;用一个很简单的图片去吸引消费者已经远远不够。想让消费者创造GMV&#xff0c;肯定需要让消费者觉得眼前一亮或是有视觉冲击的东西&#xff0c;或者在动画过程中提供更好的引导部分&#xff0c;比如红包&#xff0c;引…

Spring Cloud Gateway 原生支持接口限流该怎么玩

关于pig&#xff1a; 基于Spring Cloud、oAuth2.0开发基于Vue前后分离的开发平台&#xff0c;支持账号、短信、SSO等多种登录&#xff0c;提供配套视频开发教程。 关于 Spring Cloud Gateway SpringCloudGateway是Spring官方基于Spring 5.0&#xff0c;Spring Boot 2.0和Projec…

我的手机 不支持箭头函数

不支持&#xff0c;要换成function的形式 转载于:https://www.cnblogs.com/web-fusheng/p/7295901.html

中标麒麟linux卸载qt,国产化 银河麒麟编译Qt程序的问题汇总 | 阿拉灯

Run in terminal莫名奇妙软件无法在QtCreator中运行或者调试&#xff0c;main函数都无法进入&#xff0c;QtCreator中一运行就崩溃&#xff0c;并跳到汇编界面&#xff0c;这多半和代码没什么关系&#xff0c;我这里是将项目->运行中的“Run in terminal”去掉勾选&#xff…

css3-13 如何改变文本框的轮廓颜色

css3-13 如何改变文本框的轮廓颜色 一、总结 一句话总结&#xff1a;outline使用和border很像&#xff0c;几乎一模一样&#xff0c;多了一个offset属性 1、轮廓outline如何使用&#xff1f; 使用和border很像&#xff0c;几乎一模一样&#xff0c;多了一个offset属性 18 …

ios添加设备真机测试,以及Undefined symbols for architecture x86_64:''错误

问题今天坑了好久&#xff0c;然后找了各种资料 添加设备这个直接去开发者中心添加一个设备进去就好&#xff0c;具体流程百度&#xff0c;第二个问题是属于路径不对或者是静态库没有添加成功&#xff0c;项目可以看到&#xff0c;到时路径找不到&#xff0c;你把静态库拖到桌面…

Kinect2.0获取数据

最近事情真是多&#xff0c;今天抽空研究一下Kinec2.0的数据获取&#xff01; 系统要求 https://developer.microsoft.com/en-us/windows/kinect/hardware-setup 系统环境 联想Y430P&#xff0c;Windows10 首先安装了Kinect for Windows SDK &#xff08;KinectSDK-v2.0_1409-S…

linux超级工具,linux运维超级工具--sysdig

sysdig 是一个超级系统工具,它可以用来捕获系统状态信息&#xff0c;在运维工作中sysdig能很方便的排查异常、定位故障&#xff0c;它还能保存数据进行分析&#xff0c;并且提供强大的命令接口。在了解sysdig强大之处之前,首先得安装sysdig&#xff0c;我这里是环境是centos6.7…

Asp.net mvc 知多少(一)

本系列主要翻译自《ASP.NET MVC Interview Questions and Answers 》- By Shailendra Chauhan&#xff0c;想看英文原版的可访问http://www.dotnettricks.com/free-ebooks自行下载。该书主要分为两部分&#xff0c;ASP.NET MVC 5、ASP.NET WEB API2。本书最大的特点是以面试问答…

stm32h7能跑linux,STM32H7榨干了Cortex-M7的最后一滴血

原标题&#xff1a;STM32H7榨干了Cortex-M7的最后一滴血有个非常重磅的消息ST给自己的STM32家族又新增了一条新的产品线—— H7H 代表的是High Pefrmance之意 (此为笔者臆测)7 则表示这是基于ARM Cortex-M7架构修改而来熟悉的工程师可能会问&#xff0c;不是已经有基于M7架构的…

通过PowerShell进行网络分析

好久没有写文章&#xff0c;因为确实工作也比较忙。今天周末&#xff0c;稍微有些时间&#xff0c;在解决一个问题时&#xff0c;用到了一点抓取和处理网络数据的小技巧&#xff0c;摘录分享如下。问题描述我有一个需求&#xff0c;就是要研究某个网页加载过程中具体发起了多少…

c语言不规则窗口,C语言不规则数组和指针

不规则数组是每一行的列数不一样的二维数组&#xff0c;其原理如下图所示&#xff0c;图中的数组有3行&#xff0c;每行有不同的列数。在了解如何创建不规则数组之前&#xff0c;让我们先看一下用复合字面量创建的二维数组。复合字面量是一种C构造&#xff0c;前面看起来像类型…