ASP .NET Core 中的环境变量

在本文中,我们将通过组织一场小型音乐会(当然是在代码中)来了解 ASP .NET Core 中的环境变量。让我们从创建项目开始:

dotnet new web --name Concert

并更新Program.cs:

// replace this:

app.MapGet("/", () => "Hello World!");

// with this:

app.Logger.LogInformation("Playing {guitar} guitar", builder.Configuration["Guitar"]);

设置就是这么简单。现在让我们进行第一次声音检查:

cd Concert

dotnet run

Produces:

info: Concert[0]

Playing (null) guitar

...

好吧,这不会是一场特别精彩的音乐会null,对吧?让我们使用环境变量来解决这个问题:

export GUITAR=LesPaul && dotnet run && unset GUITAR

Output: Playing LesPaul guitar

脚本以此结束,unset以确保我们在下一个实验之前有一个干净的环境。

配置

请注意,我们Guitar不是直接以环境变量的形式访问,而是通过使用IConfiguration访问器抽象来访问。默认情况下,ASP .NET Core访问器为我们提供了另外两种使用环境变量挑选吉他的方法:

ASPNETCORE_前缀变量:

export ASPNETCORE_GUITAR=Telecaster && dotnet run && unset ASPNETCORE_GUITAR

Output: Playing Telecaster Guitar

和DOTNET_前缀变量

export DOTNET_GUITAR=SG && dotnet run && unset DOTNET_GUITAR

Output: Playing SG guitar

如果你想知道如果我们同时使用两者会发生什么,答案如下:

export ASPNETCORE_GUITAR=Telecaster DOTNET_GUITAR=SG && dotnet run && unset ASPNETCORE_GUITAR DOTNET_GUITAR

Output: Playing SG guitar

DOTNET_ prefixed variables take precedence

当然,IConfiguration不仅限于环境变量。appsettings.json还可以为我们提供配置值,所以让我们也在那里设置一把吉他:

{

"Guitar" : "Stratocaster",

...

}

并进行一些实验:

export DOTNET_GUITAR=SG && dotnet run && unset DOTNET_GUITAR

Output: Playing Stratocaster guitar

appsettings take precedence over prefixed environment variables

export GUITAR=LesPaul && dotnet run && unset GUITAR

Output: Playing LesPaul guitar

Unprefixed environment variable takes precedence over appsettings

设置配置值的另一种方法是使用命令行参数。我们已经有了appsettings值,让我们也设置环境变量,提供命令行参数,看看会发生什么:

export GUITAR=LesPaul && dotnet run --Guitar=Firebird && unset GUITAR

Output: Playing Firebird guitar

command line arguments take precedence over everything

我想强调的是,优先级和配置源列表并不是很神奇。这只是WebApplication.CreateBuilder(args)注册其配置源的一种方式。因此,如果我们扫描其内容,我们会在某处找到以下顺序的行:

configuration.AddJsonFile("appsettings.json");

configuration.AddJsonFile($"appsettings.{HostEnvironment.EnvironmentName}.json", optional: true);

configuration.AddEnvironmentVariables(prefix: "ASPNETCORE_");

configuration.AddEnvironmentVariables(prefix: "DOTNET_");

configuration.AddEnvironmentVariables();

configuration.AddCommandLine(args);

特殊环境变量

还有一些环境变量是单独使用的ASP .NET Core。为了先设置一个清晰的实验,我们Properties从项目中删除该文件夹。然后执行dotnet run将得到这样的日志:

info: Microsoft.Hosting.Lifetime[14]

Now listening on: http://localhost:5000

info: Microsoft.Hosting.Lifetime[0]

Application started. Press Ctrl+C to shut down.

info: Microsoft.Hosting.Lifetime[0]

Hosting environment: Production

有相当多的主机变量【https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-8.0#host-variables】。但ASPNETCORE_ENVIRONMENT和ASPNETCORE_URLS似乎是最重要的,研究它们应该能给我们足够的知识来流畅地操作任何其他托管变量。

export ASPNETCORE_URLS=http://+:5100 && dotnet run && unset ASPNETCORE_URLS

Outputs: Now listening on: http://[::]:5100

export ASPNETCORE_ENVIRONMENT=Wembley && dotnet run && unset ASPNETCORE_ENVIRONMENT

Outputs: Hosting environment: Wembley

请注意,宿主变量的行为可能与所有其他变量略有不同:

export ENVIRONMENT=Carnegie && dotnet run && unset ENVIRONMENT

Outputs: Hosting environment: Production

Unprefixed variable has no effect on the ASP .NET Core

确认【https://github.com/dotnet/aspnetcore/issues/55379#issuecomment-2081539608】这种差异是故意的。但并非每个主机变量都如此表现,只有"引导"变量:

export URLS=http://+:5800 && dotnet run && unset URLS

Outputs: Now listening on: http://[::]:5800

Here unprefixed variables not just affect ASP .NET Core

but take precedence over a prefixed variable

章节和下划线

Microsoft.Extensions.Configuration框架也支持嵌套配置。我们先看看它如何与基于 json 的配置一起工作。

appsettings.json:

{

"Band" : {

"LeadGuitarist" : "Clapton"

},

...

}

Program.cs:

app.Logger.LogInformation("{guitarist} playing {guitar}",

builder.Configuration["Band:LeadGuitarist"],

builder.Configuration["Guitar"]

);

//Output: Clapton playing Stratocaster

对于"嵌套"环境变量,使用双下划线:

export Band__LeadGuitarist=Hendrix && dotnet run && unset Band__LeadGuitarist

Output: Hendrix playing Stratocaster

__请注意,使用双下划线是因为:对于某些 shell(包括 bash)来说,它不是有效的标识符。

Fluent 环境变量

您可能会注意到,这Band__LeadGuitarist是一个不符合典型 shell 约定的变量名。常规格式为:BAND_LEAD_GUITARIST。关于环境变量配置提供程序,有一个好消息:

export BAND__LEADGUITARIST=Hendrix && dotnet run && unset BAND__LEADGUITARIST

Output: Hendrix playing Stratocaster

So the provider is case incensitive

但这个好消息还不足以做到这一点:

export Band_LeadGuitarist=Gilmour && dotnet run && unset Band_LeadGuitarist

Ouput: Clapton playing Stratocaster (a.k.a no effect)

Single underscore doesn't work as separator

export Band__Lead_Guitarist=Gilmour && dotnet run && unset Band__Lead_Guitarist

Ouput: Clapton playing Stratocaster (a.k.a no effect)

You can not put an arbitrary underscore, too

但是,我们可以编写自己的配置提供程序。对于每个环境变量键,我们将注册键本身以及下划线的每个可能解释的键(作为分隔符和可跳过的部分):

public static IEnumerable<string> Keys(string rawKey)

{

yield return rawKey;

var parts = rawKey.Split("_").Where(p => p != "").ToArray();

for (var i = 1; i < parts.Length; i++)

{

var beforeColon = parts.Take(i);

var afterColon = parts.Skip(i);

yield return String.Join("", beforeColon) + ":" + String.Join("", afterColon);

}

}

提供程序将加载我们可以从环境变量中获取的所有配置键值对。

public class Provider : ConfigurationProvider

{

public override void Load()

{

Data = new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);

foreach (DictionaryEntry environmentVariable in Environment.GetEnvironmentVariables())

{

var variableKey = (string)environmentVariable.Key;

var value = (string?)environmentVariable.Value;

foreach (var key in Keys(variableKey))

{

Data.Add(key, value);

}

}

}

}

我已经将提供程序制作成 nuget 包,因此您可以直接使用它:

dotnet add package Fluenv

using Fluenv;

...

builder.Configuration.AddFluentEnvironmentVariables();

然后几乎任何环境变量的命名都可以起作用,包括常规的命名:

export BAND_LEAD_GUITARIST=Gilmour && dotnet run && unset BAND_LEAD_GUITARIST

Output: Gilmour playing Stratocaster

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

相关推荐
VinciYan5 小时前
C#中通过ObjectPool重用对象提高程序性能
c#·asp.net·.net·.netcore
亦世凡华、15 小时前
从模型到视图:如何用 .NET Core MVC 构建完整 Web 应用
前端·经验分享·c#·mvc·.netcore
晓月木鱼2 天前
C# .NET CORE 开发问题汇总
.netcore
GISer_Qing2 天前
ASP.NET Core8.0学习笔记(二十六)——EF Core Include导航数据加载——显式加载
数据库·c#·.netcore·ef core·entityframework
坐井观老天2 天前
如何使用LEADTOOLS创建.NET Core跨平台OCR应用程序
c#·ocr·.netcore
.NET快速开发框架4 天前
WinForm(C/S)项目中使用矢量字体(FontAwsome、Elegant)图标
c#·.netcore·winform开发框架·快速开发框架·开发技术·rdiframework.net·企业级控件库
坐井观老天4 天前
使用SkiaSharp在C#中生成图像
c#·.netcore
GISer_Qing4 天前
ASP.NET Core8.0学习笔记(二十四)——EF Core级联插入与删除
.netcore·linq·efcore
GISer_Qing4 天前
ASP.NET Core8.0学习笔记(二十五)——EF Core Include导航数据加载之预加载与过滤
数据库·.net·.netcore·ef core