.NET 6 中的 ConfigurationManager

Intro

.NET 6 为了 Minimal API 引入了一些新东西,其中就包含了一个全新的配置对象 ConfigurationManager

这并不是 .NET Framework 里的静态类 ConfigurationManager,而是 .NET Core 里的配置 Microsoft.Extensions.Configuration 中的一个新类型,新的 ConfigurationManager 对象是之前的 ConfigurationBuilderConfigurationRoot 的结合

Implement

API Proposal:

namespace Microsoft.Extensions.Configuration
{
+    public sealed class ConfigurationManager : IConfigurationRoot, IConfigurationBuilder, IDisposable
+    {
+        public ConfigurationManager();
+        public string? this[string key] { get; set; }
+        public IConfigurationSection GetSection(string key);
+        public void Dispose();
+    }

Implement:

public sealed class ConfigurationManager : IConfigurationBuilder, IConfigurationRoot, IDisposable
{private readonly ConfigurationSources _sources;private readonly ConfigurationBuilderProperties _properties;private readonly object _providerLock = new();private readonly List<IConfigurationProvider> _providers = new();private readonly List<IDisposable> _changeTokenRegistrations = new();private ConfigurationReloadToken _changeToken = new();/// <summary>/// Creates an empty mutable configuration object that is both an <see cref="IConfigurationBuilder"/> and an <see cref="IConfigurationRoot"/>./// </summary>public ConfigurationManager(){_sources = new ConfigurationSources(this);_properties = new ConfigurationBuilderProperties(this);// Make sure there's some default storage since there are no default providers.this.AddInMemoryCollection();AddSource(_sources[0]);}// ...
}

ConfigurationManager在添加 ConfigurationSource 的时候也会注册 IConfigurationProvider,这样在添加 Source 之后就能够拿到 Configuration 中的配置了,在实现上,微软封装了一个私有的 ConfigurationSource 的类型,这里我们看一下注册配置源的代码

private class ConfigurationSources : IList<IConfigurationSource>
{private readonly List<IConfigurationSource> _sources = new();private readonly ConfigurationManager _config;public ConfigurationSources(ConfigurationManager config){_config = config;}public IConfigurationSource this[int index]{get => _sources[index];set{_sources[index] = value;_config.ReloadSources();}}public void Add(IConfigurationSource source){_sources.Add(source);_config.AddSource(source);}// ...
}

ConfigurationManager 中的 AddSource 方法实现如下:

IConfigurationBuilder IConfigurationBuilder.Add(IConfigurationSource source)
{_sources.Add(source ?? throw new ArgumentNullException(nameof(source)));return this;
}private void RaiseChanged()
{var previousToken = Interlocked.Exchange(ref _changeToken, new ConfigurationReloadToken());previousToken.OnReload();
}// Don't rebuild and reload all providers in the common case when a source is simply added to the IList.
private void AddSource(IConfigurationSource source)
{lock (_providerLock){var provider = source.Build(this);_providers.Add(provider);provider.Load();_changeTokenRegistrations.Add(ChangeToken.OnChange(() => provider.GetReloadToken(), () => RaiseChanged()));}RaiseChanged();
}

可以看到每次新加一个配置源的时候,都会去构建对应的一个 IConfigurationProvider 而且会去加载配置数据并注册配置更新事件,所以我们注册完配置之后才能够获取到配置,更多实现细节参考 Github 上的源码:https://github.com/dotnet/runtime/blob/v6.0.0-rc.1.21451.13/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationManager.cs

Sample

来看下面使用时的 Sample 吧,非常的简单

const string testKey = "test";var configuration = new ConfigurationManager();
Console.WriteLine(configuration[testKey]);configuration.AddInMemoryCollection(new Dictionary<string, string>()
{{ testKey, "test" }
});
Console.WriteLine(configuration[testKey]);
Console.ReadLine();

输出结果如下:

第一次输出的时候还没有注册配置输出的是空,第一次输出的时候已经注册了配置输出的是我们配置的值

代码示例在可以从 Github 获取 https://github.com/WeihanLi/SamplesInPractice/blob/master/net6sample/ConfigurationManagerSample/Program.cs

More

目前来说,ConfigurationManager 对象主要是为了 .NET 6 的 Minimal API 的需要,.NET 6 的 Minimal API 里用了这个,可以参考:https://github.com/dotnet/aspnetcore/blob/v6.0.0-rc.1.21452.15/src/DefaultBuilder/src/WebApplicationBuilder.cs ,但就像上面的示例一样,我们也是可以直接使用的,而且原来的 IConfigurationBuilder 依然是可以用的,无需担心升级到 .NET 6 会 break 的问题。

对于需要用到配置的测试程序直接用 ConfigurationManager 会更为简单一些,不需要先声明一个 ConfigurationBuilder 的对象注册好配置之后再构建一个 IConfiguration 对象,直接用一个对象就可以了,至少从我们写代码的角度会简单很多,但是性能会稍差一些,注册的配置源越多越明显,因为 ConfigurationManager 每次注册配置源的时候都会去构建和注册 IConfigurationProvider  而 IConfigurationBuilder 则是在最后 Build 的时候才构建一次,不过通常我们的配置也只是启动时只用配置一次,个人认为是可以接受的

References

  • https://github.com/dotnet/runtime/blob/v6.0.0-rc.1.21451.13/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationManager.cs

  • https://github.com/dotnet/runtime/blob/v6.0.0-rc.1.21451.13/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationRoot.cs

  • https://github.com/dotnet/runtime/blob/v6.0.0-rc.1.21451.13/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationBuilder.cs

  • https://github.com/dotnet/runtime/pull/55338

  • https://github.com/dotnet/runtime/issues/51770

  • https://github.com/dotnet/aspnetcore/blob/v6.0.0-rc.1.21452.15/src/DefaultBuilder/src/BootstrapHostBuilder.cs

  • https://github.com/dotnet/aspnetcore/blob/v6.0.0-rc.1.21452.15/src/DefaultBuilder/src/WebApplicationBuilder.cs

  • https://github.com/WeihanLi/SamplesInPractice/blob/master/net6sample/ConfigurationManagerSample/Program.cs

.NET 6 中的 ConfigurationManager相关推荐

  1. C# 中的 ConfigurationManager类引用方法

    c#添加了Configuration;后,竟然找不到 ConfigurationManager 这个类,后来才发现:虽然引用了using System.Configuration;这个包,但是还是不行 ...

  2. WPF项目中解决ConfigurationManager不能用(转)

    https://blog.csdn.net/MOESECSDN/article/details/78107888 在WPF项目中遇到这样的问题,做一下笔记.希望对自己和读者都有帮助. 在aap.con ...

  3. 如何在vs2010中使用ConfigurationManager

    在引用中添加两个引用,configuration和Configuration.Install(都在.NET中). 转载于:https://www.cnblogs.com/hc10/p/3371091. ...

  4. .Net2.0 使用ConfigurationManager读写配置文件

    .net1.1中如果需要灵活的操作和读写配置文件并不是十分方便,一般都会在项目中封装一个配置文件管理类来进行读写操作.而在.net2.0中使用ConfigurationManager 和WebConf ...

  5. 细聊.NET6 ConfigurationManager的实现

    前言 友情提示:建议阅读本文之前先了解下.Net Core配置体系相关,也可以参考本人之前的文章<.Net Core Configuration源码探究 [1]>然后对.Net Core的 ...

  6. 程序配置amp;amp;ConfigurationManager

    配置组件是.net framework中非常常用的功能.在创建.net framework 工程时,系统不仅会自动生成app.config文件,而且还提供了非常强大的访问类库.但是这些好东西,在.ne ...

  7. GNU Make 使用手册(于凤昌中译版)

    GNU Make 使用手册(中译版) 翻译:于凤昌 GNU make Version 3.79 April 2000 Richard M. Stallman and Roland McGrath 1 ...

  8. 微软官方的SqlHelper

    using System; using System.Data;     using System.Xml;     using System.Data.SqlClient;     using Sy ...

  9. WinForm读取指定的config文件的内容

    config文件的使用 一.缘起 最近做项目开始使用C#,因为以前一直使用的是C++,因此面向对象思想方面的知识还是比较全面的,反而是因没有经过完整.系统的.Net方面知识的系统学习,经常被一些在C# ...

最新文章

  1. Charles抓包实战详解
  2. 【LaTeX 语法】字母表示 ( 大写、小写、异体 希腊字母 | 粗体字母 | 花体字母 )
  3. 看看这14家科技前沿公司 原来最牛的天使投资是它
  4. 不同编程语言的初心和适用对象
  5. 最全的搜索引擎优化(SEO)术语表
  6. try to navigate from button to line item page
  7. Linux基础命令---mpstat显示CPU使用情况
  8. 2013年上半年工作总结,哇哈哈哈,给自己看的。
  9. java数据库实例_选择数据库实例
  10. 福布斯牛人×××先生的两个概念
  11. MongoDB-Replication Replica Set Arbiter
  12. 视频教程-JSP+Servlet实战视频课程-Java
  13. Excel中去掉多余的网格线
  14. python量化交易策略技巧与实战_量化交易策略基本框架
  15. 网络教育本科统考计算机和英语作文,远程教育本科统考英语真题及答案
  16. 【OR】线性规划(2):极方向
  17. iOS逆向:【ARM 移位操作】(LSL、ASL、LSR、ASR、ROR、RRX)
  18. 测试不同体重体型软件样子的,为什么有的人身高、体重相同,体型却不一样?这是体脂率在作祟...
  19. 苹果id退出后数据还在吗_答疑你的手机连接WiFi后,会关闭移动数据吗?
  20. 【论文阅读30】-《Autocuts: Simultaneous Distortion and Cut Optimization for UV Mapping》

热门文章

  1. 教育行业的互联网焦虑症
  2. Sersync+Rsync 增量实时同步
  3. .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  4. highgui java opencv_java – OpenCV 3.0.0 JAR缺少HighGUI
  5. mysql内连接的自连接_mysql 内连接、外连接、自连接
  6. c# 获取word表格中的内容_Java 获取、删除Word文本框中的表格
  7. [Swift]LeetCode1013. 将数组分成和相等的三个部分 | Partition Array Into Three Parts With Equal Sum...
  8. 【几何/分治】【最短路】【数学期望】Day 10.24
  9. 网络相关配置,SSH服务,bash, 元字符
  10. WPF初学——自定义样式