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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Robust Depth Enhancement via Polarization Prompt Fusion Tuning

paper&#xff1a;论文地址 code&#xff1a;github项目地址 今天给大家分享一篇2024CVPR上的文章&#xff0c;文章是用偏振做提示学习&#xff0c;做深度估计的。模型架构图如下 这篇博客不是讲这篇论文的内容&#xff0c;感兴趣的自己去看paper&#xff0c;主要是分享环境&…

NanoLog起步笔记-3-尝试解析log

nonolog起步笔记-3-尝试解析log 第一次解析sample中的nano二进制log在哪里compressedLog./decompressor decompress /tmp/logFile compressedLog是什么鬼下断分析 第一次解析 sample中的nano二进制log在哪里 如下图 手工执行的结果如下&#xff0c;不看代码&#xff0c;还真不…

Sqoop脚本编写(Mysql---->>hdfs)

目录 语法手册编写方式脚本文件类型文件编写.jar路径指定 执行效果执行方式效果 语法手册 参考博客 编写方式 脚本文件类型 只要是可读的文件即可&#xff08;.txt或者.sh等其他类型&#xff0c;不带文件后缀也可以&#xff0c;但二进制文件最好不要&#xff09; 文件编写…

一、测试工具LoadRunner Professional脚本编写-录制前设置

设置基于URL的脚本 原因:基于HTML的脚本会导致login接口不能正确录制 设置UTF-8 原因:不勾选此项会导致脚本中文变为乱码

day05-开发接口-学习记录和学习计划

1. 查询用户的课程学习记录 1.1 代码实现 Controller层&#xff1a; package com.tianji.learning.controller;import com.tianji.api.dto.leanring.LearningLessonDTO; import com.tianji.learning.service.ILearningLessonService; import com.tianji.learning.service.IL…

2022 年“泰迪杯”数据分析技能赛A 题竞赛作品的自动评判

2022 年“泰迪杯”数据分析技能赛A 题竞赛作品的自动评判 完整代码请私聊 博主 一、背景 在各类学科竞赛中&#xff0c;常常要求参赛者提交 Excel 或/和 PDF 格式的竞赛作品。 本赛题以某届数据分析竞赛作品的评阅为背景&#xff0c;要求参赛者根据给定的评分准则和标准答案&a…

AI Agent框架如何选择?LangGraph vs CrewAI vs OpenAI Swarm

介绍 由 LLMs经历了起起落落。从 2023 年 AutoGPT 和 BabyAGI 的病毒式演示到今天更精致的框架&#xff0c;AI Agent的概念——LLMs自主执行端到端任务的 LLM——既引起了人们的想象力&#xff0c;也引起了怀疑。 为什么重新引起人们的兴趣&#xff1f;LLMs 在过去 9 个月中进…

【OpenCV】平滑图像

二维卷积(图像滤波) 与一维信号一样&#xff0c;图像也可以通过各种低通滤波器&#xff08;LPF&#xff09;、高通滤波器&#xff08;HPF&#xff09;等进行过滤。LPF 有助于消除噪音、模糊图像等。HPF 滤波器有助于在图像中找到边缘。 opencv 提供了函数 **cv.filter2D()**&…

调试android 指纹遇到的坑

Android8以后版本 一、指纹服务不能自动 指纹服务fingerprintd(biometrics fingerprintservice)&#xff0c;可以手动起来&#xff0c;但是在init.rc中无法启动。 解决办法&#xff1a; 1.抓取开机时kernel log &#xff0c;确认我们的启动指纹服务的init.rc 文件有被init.c…

深度学习笔记之BERT(五)TinyBERT

深度学习笔记之TinyBERT 引言回顾&#xff1a;DistilBERT模型TinyBERT模型结构TinyBERT模型策略Transformer层蒸馏嵌入层蒸馏预测层蒸馏 TinyBERT模型的训练效果展示 引言 上一节介绍了 DistilBERT \text{DistilBERT} DistilBERT模型&#xff0c;本节将继续介绍优化性更强的知…

30.串联所有单词的子串 python

串联所有单词的子串 题目题目描述示例 1&#xff1a;示例 2&#xff1a;示例 3&#xff1a;提示&#xff1a;题目链接 题解解题思路python实现代码解释&#xff1a;提交结果 题目 题目描述 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的…

【LeetCode】498.对角线遍历

无论何时何地&#xff0c;我都认为对于一道编程题&#xff0c;思考解法的时间用于是实际动手解决问题的2倍&#xff01;如果敲键盘编码需要5min&#xff0c;那么思考解法的过程至少就需要10分钟。 1. 题目 2. 思想 其实这就是一道模拟题&#xff0c;难度中等。做这种题的关键就…

uniapp中父组件传参到子组件页面渲染不生效问题处理实战记录

上篇文件介绍了,父组件数据更新正常但是页面渲染不生效的问题,详情可以看下:uniapp中父组件数组更新后与页面渲染数组不一致实战记录 本文在此基础上由于新增需求衍生出新的问题.本文只记录一下解决思路. 下面说下新增需求方便理解场景: 商品信息设置中添加抽奖概率设置…

Flutter提示错误:无效的源发行版17

错误描述 Flutter从3.10.1 升级到3.19.4&#xff0c;在3.10.1的时候一切运行正常&#xff0c;但是当我将Flutter版本升级到3.19.4后&#xff0c;出现了下方的错误 FAILURE: Build failed with an exception.* What went wrong: Execution failed for task :device_info_plus:…

etcd的dbsize引起的集群故障

故障现象 k8s集群不能访问&#xff0c;具体表现kubectl命令不能使用。 思路 检查apiserver服务状态&#xff0c;检查etcd集群状态中errors列中存在一个alarm:NOSPACE的告警 解决&分析 具体表现 恢复使用第一&#xff0c;先尝试解除告警看能否恢复 etcdctl --endpoin…

Redis性能优化18招

Redis性能优化的18招 目录 前言选择合适的数据结构避免使用过大的key和value[使用Redis Pipeline](#使用Redis Pipeline)控制连接数量合理使用过期策略使用Redis集群充分利用内存优化使用Lua脚本监控与调优避免热点key使用压缩使用Geo位置功能控制数据的持久化尽量减少事务使…

Docker 安装 Yapi

Docker 安装系列 Docker已安装。 1、场景Yapi使用的MongoDB用户信息 1.1 创建自定义 Docker 网络 首先&#xff0c;创建一个自定义的 Docker 网络&#xff0c;以便 MongoDB 和 YApi 容器可以相互通信 [rootflexusx-328569 data]# docker network create yapi-networ…

深度学习(2)前向传播与反向传播

这一次我们重点讲解前向传播与反向传播&#xff0c;对这里还是有点糊涂 前向传播&#xff08;Forward Propagation&#xff09;和反向传播&#xff08;Backward Propagation&#xff09;是深度学习中神经网络训练的核心过程。它们分别负责计算神经网络的输出以及更新神经网络的…

Mock神器:Easy-Mock 私有化部署及使用介绍

在现代前后端分离的开发模式中&#xff0c;后端接口的数据模拟是一个常见且必要的需求。尤其是在后端接口尚未开发完成时&#xff0c;前端开发需要依赖模拟数据进行开发与测试。Easy-Mock 是一个非常流行的开源工具&#xff08;虽然它已经停止更新好长时间了&#xff09;&#…

个人IP建设:简易指南

许多个体创业者面临的一个关键挑战是如何为其企业创造稳定的需求。 作为个体创业者&#xff0c;您无法使用营销团队&#xff0c;因此许多人通过推荐和他们的网络来产生需求。因此&#xff0c;扩大您的网络是发展您的业务和产生持续需求的最佳策略。 这就是个人IP和品牌发挥作…