从零开始:如何在 .NET Core 中优雅地读取和管理配置文件
在.net中的配置文件系统支持丰富的配置源,包括文件(json、xml、ini等)、注册表、环境变量、命令行、Azure Key Vault等,还可以配置自定义配置源并跟踪配置的改变,然后按照优先级进行覆盖,总之对文件的配置有很多方法,这里我们就举几个最常用的例子来讲解。
目录
config配置管理
选项方式读取
配置提供方式
自定义配置
config配置管理
配置json文件:是目前最常用的配置文件格式,在.net中也有许多针对json文件格式进行处理的配置,这里我们可以直接在.net core项目中添加一个json文件,然后里面写一些配置信息,如下:
{"name": "test-app","age": "20","proxy": {"address": "aaa"}
}
写好config.json配置文件之后,我们需要右键其属性然后设置一下复制到最新目录的情况:

然后我们借助NuGet安装两个包,如下一个是对config配置的包,一个是对json操作的包:

然后我们执行如下语句,通过ConfigurationBuilder加载一个json配置文件,从配置中读取简单的键值对(例如 "name")以及嵌套的配置项(例如 "proxy:address"),输出读取到的配置信息:
namespace Program
{class Program{static void Main(string[] args){ConfigurationBuilder configBuilder = new ConfigurationBuilder();configBuilder.AddJsonFile("config.json", optional: true, reloadOnChange: true);IConfiguration configRoot = configBuilder.Build();string name = configRoot["name"];Console.WriteLine($"name = {name}");string address = configRoot.GetSection("proxy:address").Value;Console.WriteLine($"address = {address}");Console.ReadKey();}}
}
得到的结果如下所示:

绑定读取配置:当然我们还可以绑定一个类去自动完成配置的读取,首先我们先借助NuGet安装如下一个包:

然后我们定义一个类来映射config中的proxy配置,然后通过Get方式拿到相应数据展示:
namespace Program
{class Program{static void Main(string[] args){ConfigurationBuilder configBuilder = new ConfigurationBuilder();configBuilder.AddJsonFile("config.json", optional: true, reloadOnChange: true);IConfiguration configRoot = configBuilder.Build();Proxy proxy = configRoot.GetSection("proxy").Get<Proxy>();Console.WriteLine($"Proxy: address={proxy.Address} port={proxy.Port}");Console.ReadKey();}}class Proxy{public string Address { get; set; }public string Port { get; set; }}
}
得到的结果如下所示:

当然我们还可以直接通过Get拿到config中的数据,通过定义相关的类然后设置对应的类型即可:

选项方式读取
在读取文件中推荐使用选项方式进行读取,和DI结合方式比较好且能更好的利用reloadonchange机制,这里除了上文我们需要安装的三个包之外,这里我们还是需求安装一下下面这个包:

读取配置的时候,DI要声明IOptions<T>、IOptionsMonitor<T>、IOptionsSnapshot<T>等类型,因为IOptions<T>不会读取到新的值,和IOptionsMonitor<T>相比IOptionsSnapshot会在同一个范围内(.net core一个请求中)保持一致,因此建议使用IOptionsSnapshot<T>类型。
IOptionsSnapshot读取:在读取配置的地方,用IOptionsSnapshot<T>注入,不要在构造函数里面直接读取IOptionsSnapshot.Value而是在用到的地方再读取,否则就无法更新变化,如下所示:
在TestController中使用依赖注入模式来管理和访问配置,通过IOptionsSnapshot<Config>获取配置文件中的值(例如 name 和 age):
namespace test
{class TestController{private readonly IOptionsSnapshot<Config> optConfig;public TestController(IOptionsSnapshot<Config> optConfig){this.optConfig = optConfig;}public void Test(){Console.WriteLine(optConfig.Value.name);Console.WriteLine(optConfig.Value.age);}}
}
接下来通过通过IOptions接口来读取配置文件并将其注入到类中,
namespace Program
{class Program{static void Main(string[] args){ServiceCollection services = new ServiceCollection();services.AddScoped<TestController>();ConfigurationBuilder configBuilder = new ConfigurationBuilder();configBuilder.AddJsonFile("config.json", optional: true, reloadOnChange: true);IConfiguration configRoot = configBuilder.Build();services.AddOptions().Configure<Config>(e => configRoot.Bind(e));using(var sp = services.BuildServiceProvider()){var test = sp.GetRequiredService<TestController>();test.Test();}Console.ReadKey();}}class Config{public string name { get; set; }public string age { get; set; }public Proxy Proxy { get; set; }}class Proxy{public string Address { get; set; }public string Port { get; set; }}
}
如下执行通过使用ServiceProvider获取TestController实例,TestController在构造时自动注入配置,最后TestController调用了Test()方法输出配置文件中的name、age详细信息:

配置提供方式
读取调试参数:配置文件除了上面讲解的读取config等配置文件的方式外,框架还支持从命令行参数、环境变量等地方读取, 借助NuGet安装如下的包进行使用:

安装完包之后,我们将之前加载json文件的格式修改为命令行的形式,如下:

然后我们右键我们的项目选择属性,然后找到调试的按钮,输入相关的参数信息即可,对于环境变量或命令行等简单的键值对结构,如果想要进行复杂结构的配置,需要进行扁平化处理,对于配置的名字需要采用“层级配置”,例如:a:b:c 赋值的话这样配置 a:b:c:0,例如:
name=zhangsan;age=18;proxy:address=aaa;proxy:port=80;
proxy:ids:0=3;proxy:ids:1=5;

输入完成之后我们的项目会自动生成一个配置文件,然后我们运行项目之后就会打印该文件内容:

读取环境变量:如果想读取环境变量中的数据的话,可以借助NuGet安装如下的包

然后我们在环境变量中配置如下的数据,VS调试时为了避免修改系统环境变量,可以直接在VS中设置环境变量的方法:

然后我们就可以我们在使用环境变量的函数获取当前环境变量的数据,该函数是有参数和没有参数两种情况的,无参数版本会把程序相关的所有环境变量都加载进来,由于有可能和系统中已有的环境变量冲突,因此这边可以建议使用有prefix参数进行配置读取的,读取配置的时候prefix参数会被忽略:

当然.net core还支持其他配置源,例如ini、xml等格式的配置源,还支持在运行或调试时加载不同的json文件,而且还内置了第三方支持中心化配置服务器,例如Azure、阿里云等,具体使用可以查询相关文档,这里不再赘述。
自定义配置
.net core中不建议使用.net framework里的web.config,不过仍继续提供ConfigurationManager,不过官方没有支持通过新的Configuration框架读取方式,这里我们建议自行编写一个自定义配置提供者,实际使用意义不大,主要还是了解读取配置的方法。具体步骤如下:
编写ConfigurationProvider类实际读取配置:
开发一个直接或间接实现IConfigurationProvider接口的类xxxConfigurationProvider,一般继承自ConfigurationProvider,如果是从文件读取是可以继承自FileConfigurationProvider,重写Load方法把扁平化数据设置到Data属性即可。
ConfigurationSource在Build中返回ConfigurationProvider对象:
开发一个实现IConfigurationSource接口的类xxxConfigurationSource,如果是从文件读取可以继承自FileConfigurationSource,在Build方法中返回上面的ConfigurationProvider对象。
ConfigurationSource对象加入IConfigurationBuilder:
使用configurationBuilder.Add(new ConfigurationSource())即可,为了简化使用一般还提供一个IConfigurationBuilder的扩展方法。
相关文章:
从零开始:如何在 .NET Core 中优雅地读取和管理配置文件
在.net中的配置文件系统支持丰富的配置源,包括文件(json、xml、ini等)、注册表、环境变量、命令行、Azure Key Vault等,还可以配置自定义配置源并跟踪配置的改变,然后按照优先级进行覆盖,总之对文件的配置有很多方法,这…...
JVM学习:CMS和G1收集器浅析
总框架 一、Java自动内存管理基础 1、运行时数据区 运行时数据区可分为线程隔离和线程共享两个维度,垃圾回收主要是针对堆内存进行回收 (1)线程隔离 程序计数器 虚拟机多线程是通过线程轮流切换、分配处理器执行时间来实现的。为了线程切换…...
Science Robotics让软机器人“活”得更久的3D打印!
软机器人硬件在医疗、探索无结构环境等领域有广泛应用,但其生命周期有限,导致资源浪费和可持续性差。软机器人结合软硬组件,复杂组装和拆卸流程使其难以维修和升级。因此,如何延长软机器人的生命周期并提高其可持续性成为亟待解决…...
模电面试——设计题及综合分析题0x01(含答案)
1、已知某温控系统的部分电路如下图(EDP070252),晶体管VT导通时,继电器J吸合,压缩机M运转制冷,VT截止时,J释放,M停止运转。 (1)电源刚接通时,晶体…...
二层交换机和三层交换机
一、交换机简述 交换机的主要功能包括物理编址、网络拓扑结构、错误校验、帧序列以及流控。交换机还具备了一些新的功能,如对VLAN(虚拟局域网)的支持、对链路汇聚的支持,甚至有的还具有防火墙的功能。 交换机除了能够连接同种类型…...
每天五分钟机器学习:凸集
本文重点 在SVM中,目标函数是一个凸函数,约束集合是一个凸集。因此,SVM问题可以转化为一个凸规划问题来求解。这使得SVM在实际应用中具有较高的计算效率和准确性。 凸集的定义 凸集是指一个集合中的任意两点之间的线段都完全包含在这个集合中。换句话说,给定集合C中的两…...
Mongodb日志报错too many open files,导致mongod进程down
【解决方案】 (1)进入到服务器,执行: ulimit -a 查看:open files这一行的数量,如果查询到的结果是1000左右,那多半是服务器限制。 (2)在当前session窗口执行如下&…...
关于 PCB线路板细节锣槽问题 的解决方法
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/144783817 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…...
硬件基础知识笔记(2)——二级管、三极管、MOS管
Part 2 二级管、三极管、MOS管 1、二级管1.1肖特基二极管和硅二极管选型比较1.2到底是什么决定了二极管的最高工作频率?1.3二极管结电容和反向恢复时间都是怎么来的 1、二级管 1.1肖特基二极管和硅二极管选型比较 肖特基二极管的优势主要在速度和压降,对…...
软件测试之非功能测试设计
非功能测试设计 非功能:除了软件功能测试,其他都是非功能测试。 1.兼容 2.易用 3.性能(专项) 4.安全(专项) Web浏览器 兼容:Chrome浏览器、Edge浏览器、Firefox浏览器、Safari苹果浏览器 易用:参考竞品,主观感受为主 总结 1.非功能测试范围 兼容性、…...
GPU 英伟达GPU架构回顾
1999 年,英伟达发明了 GPU(graphics processing unit),本节将介绍英伟达 GPU 从 Fermi 到 Blackwell 共 9 代架构,时间跨度从 2010 年至 2024 年,具体包括费米(Feimi)、开普勒&#…...
机器学习 - 线性回归
线性回归模型的定义 线性回归(Linear Regression)的目标旨在找到可以描述目标值(输出变量)与一个或多个特征(输入变量)之间关系的一个线性方程或函数。 线性回归模型的表达式为 线性回归模型表达式的“齐次…...
NestJS 性能优化:从应用到部署的最佳实践
在上一篇文章中,我们介绍了 NestJS 的微服务架构实现。本文将深入探讨 NestJS 应用的性能优化策略,从应用层到部署层面提供全方位的优化指南。 应用层优化 1. 路由优化 // src/modules/users/users.controller.ts import { Controller, Get, UseInter…...
本地快速推断的语言模型比较:Apple MLX、Llama.cpp与Hugging Face Candle Rust
本地快速推断的语言模型比较:Apple MLX、Llama.cpp与Hugging Face Candle Rust 在自然语言处理(NLP)部署中,推断速度是一个关键因素,尤其是对于支持大型语言模型(LLM)的应用来说。随着Apple M1…...
您的公司需要小型语言模型
当专用模型超越通用模型时 “越大越好”——这个原则在人工智能领域根深蒂固。每个月都有更大的模型诞生,参数越来越多。各家公司甚至为此建设价值100亿美元的AI数据中心。但这是唯一的方向吗? 在NeurIPS 2024大会上,OpenAI联合创始人伊利亚…...
智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之14 方案再探 之5:知识树三类节点对应的三种网络形式及其网络主机
本文要点 前面讨论过(前面有错这里做了修正),三种簿册归档 对应通过不同的网络形式(分布式、对等式和去中心式)。每种网络主机上分别提供: 分布式控制脚本、 对等式账本 和 备记手本 通过以上讨论&#x…...
JR-RLAA系20路模拟音频多功能编码器
JR-RLAA系20路模拟音频多功能编码器 产品特色 (1)工业级19英寸标准设备,内置双电源 (2)内嵌Web Server,支持远程Web页面登陆后的统一配置操作 (3)支持20路音频输入 (4)支持Dolby Digital(AC-3) ,MPEG-2,AAC-LC/HE-AAC&#x…...
LabVIEW冷却风机性能测试系统
开发了基于LabVIEW软件及LabSQL工具包的冷却风机性能测试系统。系统通过高效的数据库访问技术,实现了对冷却风机测试过程中关键性能数据的采集、存储与管理,优化了测试流程并提升了数据处理的效率。 项目背景 在工业生产和科研测试中,准…...
Python-Pdf转Markdown
使用pdfminer.sixmarkdownify pdfminer.six可以提取Pdf文本内容markdownify可以将文本内容写markdown文件 安装 pip install pdfminer.six pip install markdownify实现 from pdfminer.high_level import extract_text from markdownify import markdownifydef pdf2markdo…...
pyQT + OpenCV相关练习
一、设计思路 1、思路分析与设计 本段代码是一个使用 PyQt6 和 OpenCV 创建的图像处理应用程序。其主要功能是通过一个图形界面让用户对图片进行基本的图像处理操作,如灰度化、翻转、旋转、亮度与对比度调整,以及一些滤镜效果(模糊、锐化、边…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...
