深入理解.NET Core中的配置Configuration和应用
笔记哥 /
04-18 /
39点赞 /
0评论 /
511阅读
## 什么是配置
.NET中的配置,本质上就是key-value键值对,并且key和value都是字符串类型。
在.NET中提供了多种配置提供程序来对不同的配置进行读取、写入、重载等操作,这里我们以为.NET 的源码项目为例,来看下.NET中的配置主要是有那些类库。下面这个截图是.NET 源码中和配置相关的所有类库,所有配置相关的类库都是都是以Microsoft.Extensions.Configuration开头的。

貌似很多,没关系我们来简单理解一下。
| 类库名称 | 类库作用 |
| --- | --- |
| 1、Microsoft.Extensions.Configuration.Abstractions | 定义配置相关的接口,其他所有配置类库都必须引用这个类库 |
| 2、Microsoft.Extensions.Configuration | Microsoft.Extensions.Configuration.Abstractions类库的简单实现 |
| 3、配置提供程序:Microsoft.Extensions.Configuration.CommandLine | 基于命令行的配置提供程序,负责对命令行的配置进行读写、载入、重载等操作。 |
| 4、配置提供程序:Microsoft.Extensions.Configuration.EnvironmentVariables | 基于环境变量的配置提供程序,负责对环境变量的配置进行读写、载入、重载等操作 |
| 5、配置提供程序:Microsoft.Extensions.Configuration.FileExtensions | 基于的文件提供程序的基类库,文件提供程序包括基于Json文件、Ini文件、Xml文件或者自定义文件等。 |
| 6、配置提供程序:Microsoft.Extensions.Configuration.Json | 基于Json文件的配置提供程序程序,负责从Json文本文件中对配置读写、载入、重载等操作。 |
| 7、配置提供程序:Microsoft.Extensions.Configuration.Ini | 基于Ini文件的配置提供程序,负责从Ini文件中对配置进行读写、载入、重载等操作。 |
| 8、配置提供程序:Microsoft.Extensions.Configuration.UserSecrets | 基于UserSecrets的配置提供程序,这个本质上也是一种基于Json文件类型的配置程序。主要用于管理应用机密 |
| 9、Microsoft.Extensions.Configuration.Binder | 负责将key-value键值对的配置列表绑定到指定的C#实体类上,方便程序使用。 |
从上面可以看到,主要有四个类库:第1个类库`Abstractions`负责定义配置的一些接口,第2个类库`Configuration`负责定义配置的简单实现。第3到第8个类库都是具体的配置提供程序,第9个类库`Binder`负责将配置绑定到指定的的Model,方便程序使用。
配置提供程序,.NET中有多个类库提供程序,每个类库提供程序都是以单独的类库向外提供,基本上每个类库就是三个文件,分别是ConfigurationExtensions.cs、ConfigurationProvider.cs和ConfigurationSource.cs,这三个类分别表示配置的扩展方法、配置提供程序和配置源。配置源用于生成配置提供程序。
在第2个类库中,微软帮助我们实现了一个基于类库的配置提供程序,我们在列表中没有单独列举这个类库提供程序。
## 配置源IConfigurationSource
配置源表示一个单独的配置集合,可以表示来自内存的配置源、来自Json文件的配置源。但是配置源不直接提供对配置的访问操作,它只有一个接口`Build`,该接口一个具体的配置提供程序`IConfigurationProvider `,每个配置提供程序负责对配置的读取、写入、载入配置、重载配置等访问操作。
```csharp
public interface IConfigurationSource
{
IConfigurationProvider Build(IConfigurationBuilder builder);
}
```
## 配置提供程序IConfigurationProvider
配置提供程序负责实现配置的设置、读取、重载等功能,并以键值对形式提供配置。
```csharp
public interface IConfigurationProvider
{//读取配置
bool TryGet(string key, out string? value);
//修改配置
void Set(string key, string? value);
//获取重载配置的Token
IChangeToken GetReloadToken();
//载入配置
void Load();
//获取指定父路径下的直接子节点Key,然后 Concat(earlierKeys) 一同返回
IEnumerable GetChildKeys(IEnumerable earlierKeys, string? parentPath);
}
```
## 配置构建者IConfigurationBuilder
上面的IConfigurationSource和IConfigurationProvider分别表示一种数据源和对一种数据源进行读写操作。但是一个程序的配置可能来自很多地方,可能一部分配置来自环境变量、一部分配置来自文件等等。这个时候IConfigurationBuilder配置构建者就诞生了,IConfigurationBuilder接口维护了多个配置源,并提供一个Build方法生成一个统一的配置`IConfigurationRoot `来统一对整个程序的配置进行读取、写入、重载等操作。但是这里大家注意,`IConfigurationRoot `对配置的访问,本质上还是通过配置提供程序`IConfigurationProvider`来进行的。
假设,当我们查找一个Key为Name的配置,`IConfigurationRoot `内部会遍历所有`Sources `属性生成的`IConfigurationProvider`,然后依次调用`IConfigurationProvider`的TryGet来获取Name的具体配置数据。
```csharp
public interface IConfigurationBuilder
{//保存Build的一些公开的字典属性,有需要的化可以使用该字段存放一些变量
IDictionary Properties { get; }
//来自多个地方的配置源集合
IList Sources { get; }
//向Sources属性中添加一个配置源
IConfigurationBuilder Add(IConfigurationSource source);
//基于所有配置源生成一个全局的配置,供程序读写,一般我们都是用这个接口对配置进行读写。
IConfigurationRoot Build();
}
```
## 配置构建者实现类ConfigurationBuilder
在具体的配置构建者的Build方法中,我们可以看到,它依次调用`IConfigurationProvider`的Buid方法生成多个配置提供程序`IConfigurationProvider `,然后将所有的配置提供程序`providers `传给了`ConfigurationRoot`。`ConfigurationRoot`正是调用`providers `的一系列方法实现对配置的读取、写入、重载等操作。
```csharp
public class ConfigurationBuilder : IConfigurationBuilder
{
private readonly List _sources = new();
public IList Sources => _sources;
public IDictionary Properties { get; } = new Dictionary();
public IConfigurationBuilder Add(IConfigurationSource source)
{
ThrowHelper.ThrowIfNull(source);
_sources.Add(source);
return this;
}
public IConfigurationRoot Build()
{
var providers = new List();
foreach (IConfigurationSource source in _sources)
{
IConfigurationProvider provider = source.Build(this);
providers.Add(provider);
}
return new ConfigurationRoot(providers);
}
}
```
## 配置接口IConfiguration
这个接口就是最核心的配置接口,提供了对配置的读取、写入、重载等操作,它的实现类是`ConfigurationRoot`,上面我们已经介绍过,`IConfiguration`本身还是通过各个配置提供程序对配置进行访问操作。
```csharp
public interface IConfiguration
{//获取或设置配置
string? this[string key] { get; set; }//获取指定key的配置子节点
IConfigurationSection GetSection(string key);//获取当前配置的直接子节点列表
IEnumerable GetChildren();
//当配置发生变更时的token
IChangeToken GetReloadToken();
}
```
## 配置接口IConfigurationRoot
IConfigurationRoot其实是配置的根接口,该接口有个最重要的属性`Providers `负责保存所有的配置提供程序,`IConfiguration`对配置的访问,就是通过遍历这个`Providers`来访问的。
```csharp
public interface IConfigurationRoot : IConfiguration
{//强制重载所有配置
void Reload();
//所有配置提供程序
IEnumerable Providers { get; }
}
```
## 实现自定义配置提供程序
实现自定义配置提供程序,其实只需要实现三个类就可以,一个是配置源、一个是配置提供程序、一个是针对当前配置的扩展方法。第三个类可有可无,不过我们一般都要实现。我们来参考下基于命令行的配置提供程序类库的文件。

接下来,我们来实现一个基于数据库的配置提供程序,分别实现配置源`DataBaseConfigurationSource `、配置提供程序`DataBaseConfigurationExtensions `和扩展方法类`DataBaseConfigurationExtensions`,当然在这里我们只做对应的演示,没有实现具体的配置方法。
```csharp
public class DataBaseConfigurationSource : IConfigurationSource
{
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new DataBaseConfigurationProvider();
}
}
public class DataBaseConfigurationProvider : ConfigurationProvider
{
public override void Load()
{
base.Load();
//读取数据库配置
}
}
public static class DataBaseConfigurationExtensions
{
public static IConfigurationBuilder AddDb(this IConfigurationBuilder configurationBuilder)
{
configurationBuilder.Sources.Add(new DataBaseConfigurationSource());
return configurationBuilder;
}
}
```
## 调用自定义配置程序
```csharp
static void Main(string[] args)
{
var builder = new ConfigurationBuilder()
.AddDb()
.Build();
var value = builder["key"];
}
```
本文来自投稿,不代表本站立场,如若转载,请注明出处:http//www.knowhub.vip/share/2/2363
- 热门的技术博文分享
- 1 . ESP实现Web服务器
- 2 . 从零到一:打造高效的金仓社区 API 集成到 MCP 服务方案
- 3 . 使用C#构建一个同时问多个LLM并总结的小工具
- 4 . .NET 原生驾驭 AI 新基建实战系列Milvus ── 大规模 AI 应用的向量数据库首选
- 5 . 在Avalonia/C#中使用依赖注入过程记录
- 6 . [设计模式/Java] 设计模式之工厂方法模式
- 7 . 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
- 8 . SQL 中的各种连接 JOIN 的区别总结!
- 9 . JavaScript 中防抖和节流的多种实现方式及应用场景
- 10 . SaltStack 远程命令执行中文乱码问题
- 11 . 推荐10个 DeepSeek 神级提示词,建议搜藏起来使用
- 12 . C#基础:枚举、数组、类型、函数等解析
- 13 . VMware平台的Ubuntu部署完全分布式Hadoop环境
- 14 . C# 多项目打包时如何将项目引用转为包依赖
- 15 . Chrome 135 版本开发者工具(DevTools)更新内容
- 16 . 从零创建npm依赖,只需执行一条命令
- 17 . 关于 Newtonsoft.Json 和 System.Text.Json 混用导致的的序列化不识别的问题
- 18 . 大模型微调实战之训练数据集准备的艺术与科学
- 19 . Windows快速安装MongoDB之Mongo实战
- 20 . 探索 C# 14 新功能:实用特性为编程带来便利
- 相关联分享
- .NET 原生驾驭 AI 新基建实战系列Milvus ── 大规模 AI 应用的向量数据库首选
- 关于 Newtonsoft.Json 和 System.Text.Json 混用导致的的序列化不识别的问题
- .NET Core中的配置Configuration实战
- 常用的 Visual Studio 2022 扩展插件推荐:生产力必备工具
- 在 .NET 中使用 Sqids 快速的为数字 ID 披上神秘短串,轻松隐藏敏感数字!
- .NET 10 进展之 CoreCLR Interpreter
- 一款基于 .NET 开源、可以拦截并修改 WinSock 封包的 Windows 软件
- 一款 .NET 开源、免费、轻量级且非侵入性的防火墙软件
- 解锁.NET 9性能优化:内存、异步、代码与Web全方位指南
- 使用MCP C# SDK开发MCP Server + Client
- Gradio.Net:加速 .NET 的 Web 应用开发
- Magick.NET 支持100多种格式的强大 .NET 图片处理库
- 2025年C#/.NET/.NET Core优秀项目和框架推荐
- EF Core 10 中 LeftJoin 和 RightJoin 运算符在 LINQ 查询中的应用
- [开源][.Net Framework 4.0] SimpleLiveDataFeed v1.0更新:增加NuGet包
- .NET 10 Preview 4中ASP.NET Core 改进
- ASP.NET Core 实现的领域驱动设计框架推荐
- 如何在 .NET 中 使用 ANTLR4
- 如何把ASP.NET Core WebApi打造成Mcp Server
- .NET 开源工业视觉系统 OpenIVS 快速搭建自动化检测平台
- C#/.NET/.NET Core技术前沿周刊 | 第 39 期(2025年5.19-5.25)
- C# LINQ 快速入门实战指南,建议收藏学习!
- 解决.NET AOT交叉编译到Linux - arm64的坑
- 10年+.NET Coder 心语 ── 单一职责原则的思维:为什么你的代码总在"牵一发而动全身"
- 3款基于.NET开源且免费的远程桌面工具分享
- 深入理解.NET Core中的配置Configuration和应用
- ASP.NET Core EFCore 属性配置与DbContext 详解
- .NET 的全新低延时高吞吐自适应 GC - Satori GC