【NetCore】06-配置框架

news2025/1/18 18:14:11

文章目录

    • 1.配置框架
      • 1.1 核心包
      • 1.2 配置框架核心类型
      • 1.3 配置框架扩展点
    • 2.命令行配置提供程序
      • 2.1 支持的命令格式
      • 2.2 命令替换模式
    • 3. 环境变量配置提供程序
      • 3.1 使用场景
      • 3.2 特性
    • 4.文件配置提供程序
      • 4.1 文件配置提供程序
      • 4.2 特性
    • 5.配置变更监听-配置热更新能力的核心
      • 5.1 场景
      • 5.2 关键方法
    • 6.配置绑定-使用强类型对象承载配置数据
      • 6.1 要点
    • 7.自定义配置数据源-低成本实现定制化配置方法
      • 7.1 扩展步骤

1.配置框架

1.1 核心包

  • Microsoft.Extensions.Configuration.Abstractions
  • Microsoft.Extensions.Configuration

以Key-value键值对方式抽象配置,支持从不同数据源读取配置,如环境变量,数据库等

1.2 配置框架核心类型

  • IConfiguration
  • IConfigurationRoot
  • IConfigurationSection
  • IConfigurationBuilder

1.3 配置框架扩展点

  • IConfigurationSource
  • IConfigurationProvider
static void Main(string[] args)
{
	IConfigurationBuilder builder = new ConfigurationBuilder();
	
	builder.AddInMemoryCollection(new Dictionary<string,string>()// 注入内存的配置数据源
	{
		{"key1","value1"},
		{"key2","value2"},
		{"section1:key4","value4"} ,// section用于配置分组
		{"section2:key5","value5"} ,
		{"section2:key6","value6"} ,
		{"section2:section3:key7","value7"} ,// 多层嵌套
	});
	
	IConfigurationRoot configurationRoot = builder.Build();// 构建所有配置

	Console.WriteLine(configurationRoot["key1"]);// 读取配置
	Console.WriteLine(configurationRoot["key2"]);
	
	// 获取section
   IConfigurationSection section = configurationRoot.GetSection("sction1");
   Console.Writeline(section["key4"]); // 输出结果为 value4
   Console.WriteLine(section["key5"]); // 无法获取值
   
    IConfigurationSection section2 = configurationRoot.GetSection("sction2");
    Console.WriteLine(section["key5"]); // 输出结果为value5
    
    var section3 = section2.GetSection("section3");// 多层嵌套的读取
    Console.WriteLine(section3["key7"]);// 输出结果为value7
}


2.命令行配置提供程序

2.1 支持的命令格式

  • 无前缀的key=value 模式
  • 双中横线模式 --key=value 或 – key value
  • 正斜杠模式 /key=value 或 /key value

备注 : 等号分隔符和空格分隔符不能混用

2.2 命令替换模式

就是可以给命令取别名

  • 必须以单划线(-)或双划线(–)开头
  • 映射字典不能包含重复key
// 控制台应用程序
static void Main(string[] args)
{
	var builder = new ConfigurationBuilder();
	builder.AddCommandLine(args);
	
	// 命令替换
	//var mapper = new Dictionary<string,string>{{"-k1","CommandLineKey1"}};// 把-k1的值换给CommandLineKey1
	//builder.AddCommandLine(args,mapper);

	var configurationRoot = builder.Builder();
	Console.WriteLine($"CommandLineKey1:{configurationRoot["CommandLineKey1"]}");
	Console.ReadKey();
}

在项目属性-调试-应用程序参数中设置启动参数 ,设置四个参数

CommandLineKey1=value1 --CommandLineKey2=value2 /CommandLineKey3=value3 -k1=k3

3. 环境变量配置提供程序

3.1 使用场景

  • 在Docker中运行时
  • 在Kubernetes中运行时
  • 需要配置Asp.NetCore的一些内置特殊配置时

3.2 特性

  • 对于配置的分层键,支持用双下横线"__“代替”:"
  • 支持根据前缀加载
static void Main(string[] args)
{
	var builder = new ConfigurationBuilder();
	builder.AddEnvironmentVariables();
	
	var configurationRoot = builder.Builder();
	Console.WriteLine($"key1:{configurationRoot["CommandLineKey1"]}");
	
	// 分层键
	var section = configurationRoot.GetSection("SECTION1");
	Console.WriteLine($"KEY3:{section["KEY3"]}"); // 输出为 : value3

   // 前缀过滤
   builder.AddEnvironmentVariables("XIAO_");
   var configurationRoot = builder.Builder();
   Console.WriteLine($"key1:{configurationRoot["KEY1"]}");
   
}

环境变量配置:
项目右键-属性-调试,设置环境变量
在这里插入图片描述

4.文件配置提供程序

4.1 文件配置提供程序

  • Micosoft.Extensions.Configuration.Ini
  • Micosoft.Extensions.Configuration.Json
  • Microsoft.Extensions.Configuration.NewtonsoftJson
  • Microsoft.Extensions.Configuration.Xml
  • Microsoft.Extensions.Configuration.UserSecrets

4.2 特性

  • 指定文件可选、必选
  • 指定是否监视文件的变更
// 控制台程序
static void Main(string[] args)
{ 
	var builder = new ConfigurationBuilder();
	// optional表示文件是否可选,默认为false,表示文件不存在时会报错
	// reloadChange表示文件变更是否重新读取,默认为true
	builder.AddJsonFile("appsettings.json",optional:false,reloadOnChange:true);
	builder.AddIniFile("appsetting.ini");// 这个配置会覆盖前面的配置信息,优先级更高
	var configurationRoot = builder.Builder();

	Console.WriteLine($"Key1:{configurationRoot["Key1"]}");// 输出结果 value1
	Console.WriteLine($"Key2:{configurationRoot["Key2"]}");// 输出结果value2
	Console.WriteLine($"Key3:{configurationRoot["Key3"]}");// 输出为空
	Console.ReadKey();
}

引用程序包
在这里插入图片描述

appsettings.json配置
在这里插入图片描述

5.配置变更监听-配置热更新能力的核心

5.1 场景

  • 需要记录配置源的变更时
  • 需要在配置数据变更时触发特定操作时

5.2 关键方法

  • IChangeTokenIconfiguration.GetReloadToken()
// 控制台程序
static void Main(string[] args)
{ 
	var builder = new ConfigurationBuilder();
	builder.AddJsonFile("appsettings.json",optional:true,reloadOnChange:true);
	var configurationRoot = builder.Builder();

	IChangeToken token =  configurationRoot.GetReloadToken();//IChangeToken只能使用一次

	ChangeToken
	
	token.RegisterChageCallback(state => { // 修改配置文件时读取
		Console.WriteLine($"Key1:{configurationRoot["Key1"]}");
		Console.WriteLine($"Key2:{configurationRoot["Key2"]}");
		Console.WriteLine($"Key3:{configurationRoot["Key3"]}");
	},configurationRoot);
	Console.ReadKey();
	
	//Console.WriteLine($"Key1:{configurationRoot["Key1"]}");
	//Console.WriteLine($"Key2:{configurationRoot["Key2"]}");
	//Console.WriteLine($"Key3:{configurationRoot["Key3"]}");
	//Console.ReadKey();
}

appsettings.json配置
在这里插入图片描述
注意:这里只能监听到一次配置文件的修改,修改一次后再次修改,将无法捕获到修改信息
因为IChangeToken对象只能使用一次,如果需要持续监听,需要在结束后重新获取一次IChangeToken,如下代码所示

// 改进后代码
// 控制台程序
static void Main(string[] args)
{ 
	var builder = new ConfigurationBuilder();
	builder.AddJsonFile("appsettings.json",optional:true,reloadOnChange:true);
	var configurationRoot = builder.Builder();

	IChangeToken token =  configurationRoot.GetReloadToken();//IChangeToken只能使用一次
	// 持续监听修改
	ChangeToken.OnChange(() => configurationRoot.GetReloadToken(),()=>
	{
		Console.WriteLine($"Key1:{configurationRoot["Key1"]}");
		Console.WriteLine($"Key2:{configurationRoot["Key2"]}");
		Console.WriteLine($"Key3:{configurationRoot["Key3"]}");
	});
	Console.ReadKey();
}


6.配置绑定-使用强类型对象承载配置数据

6.1 要点

  • 支持将配置值绑定到已有对象
  • 支持将配置值绑定到私有属性上(默认情况只能绑定public属性)

// 控制台程序
static void Main(string[] args)
{ 
	var builder = new ConfigurationBuilder();
	builder.AddJsonFile("appsettings.json",optional:true,reloadOnChange:true);
	var configurationRoot = builder.Builder();
	
	var config = new Config();
	config.Key1 = "config key1";
	config.Key5 = true;
	config.Key6 = 100;
	
	configurationRoot.Bind(config);
	//configurationRoot.GetSection("section名称").Bind(config);//多层级绑定
	Console.WriteLine($"Key1:{config.Key1}");// 输出Key1:Value1
	Console.WriteLine($"Key5:{config.Key5}");// 输出Key5:false
	Console.WriteLine($"Key6:{config.Key6}");// 输出Key6:10
}


class Config
{
	public string Key1 { get; set;}
	public bool Key5 { get; set;}
	public int Key6 { get; set;}
}


appsettings.json配置
在这里插入图片描述

通常会遇到多层级的配置,采用如下方式

static void Main(string[] args)
{ 
	var builder = new ConfigurationBuilder();
	builder.AddJsonFile("appsettings.json",optional:true,reloadOnChange:true);
	var configurationRoot = builder.Builder();
	
	var config = new Config();
	config.Key1 = "config key1";
	config.Key5 = true;
	config.Key6 = 100;
	
	configurationRoot.GetSection("OrderService").Bind(config,binderOptions => {
				binderOptions.BindNonPublicProperties = true; //BindNonPublicProperties 私有属性是否绑定.默认false
			});//多层级绑定
	Console.WriteLine($"Key1:{config.Key1}");// 输出Key1:order key1
	Console.WriteLine($"Key5:{config.Key5}");// 输出Key5:true
	Console.WriteLine($"Key6:{config.Key6}");// 输出Key6:200
	// 读取到的是appsettings.json中内容
}

对应的appsettings.json如下
在这里插入图片描述

一般推荐使用强类型进行绑定,Bind方法在开发中使用会比较多

7.自定义配置数据源-低成本实现定制化配置方法

7.1 扩展步骤

  • 实现IConfigurationSource
  • 实现IConfigurationProvider
  • 实现Addxxx扩展方法

IConfigurationSource

	class MyConfigurationSource : IConfigurationSouce
	{
		public IConfigurationProvider Builde(IConfigurationBuilder builder)
		{
			return new MyConfigurationProvider();
		}
	}

	using System.Timers.Timer;
	public class MyConfigurationProvider : ConfigurationProvider
    {
        Timer timer;

        public MyConfigurationProvider() : base()
        {
            timer = new Timer();
            timer.Elapsed += Timer_Elasped;
            timer.Interval = 3000;
            timer.Start();
        }

        private void Timer_Elasped(object? sender, ElapsedEventArgs e)
        {
            Load(true);
        }

        public override void Load()
        {
            // 加载数据
            Load(false);
        }

        void Load(bool reload)
        {
            this.Data["lastTime"] = DateTime.Now.ToString();
            if (reload)
            {
                base.OnReload();
            }
        }
    }

	// 定义扩展方法,暴露在外的扩展方法,不需要将具体的配置源实现向外暴露
	namespace Microsoft.Extensions.Configuration // 使用Configuration命名空间
	{
	    public static class MyConfigurationBuilderExtensions
	    {
	        public static IConfigurationBuilder AddMyConfiguration(this IConfigurationBuilder builder)
	        {
	            builder.Add(new MyConfigurationSource());
	            return builder;
	        }
	    }
	}

	static void Main(string[] args)
	{
		var builder = new ConfigurationBuilder();
		//builder.Add(new MyConfigurationSource());// 直接读取具体配置
		builder.AddMyConfiguration();/ 通过扩展方法获取
		
		var configRoot = builder.Build();
		// 持续监听
		ChangeToken.OnChange(() => configRoot.GetReloadToken(), () =>
		{
		    var value = configRoot["lastTime"];
		    Console.WriteLine(value);
		});

		Console.WriteLine("开始了");
		Console.ReadKey();
	}

定义扩展时,将具体的实现定义为私有的internal,然后通过扩展方法的方式暴露出去
输出结果
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

客服如何通过微信接收消息通知-唯一客服文档中心

当我们在自己网站上嵌入对接了客服代码&#xff0c;我们想要通过微信接收访客的消息提醒通知&#xff0c;可以通过扫描客服后台的微信二维码&#xff0c;即时收消息通知提醒。 我们网站地址&#xff1a;gofly.v1kf.com 客服后台 后台主页面板&#xff0c;就展示了一个微信二维码…

PHP http请求封装使用(POST.GET,PUT,DELETE)

封装的 sendRequest() 函数是一个通用的发送请求函数&#xff0c;可以发送 POST、GET、PUT、DELETE 请求。下面对该函数的代码进行具体讲解&#xff1a; <?php function sendRequest($method, $url, $data null, $contentType multipart/form-data, $headers array(),…

无人驾驶实战-第一课(自动驾驶概述)

在七月算法上报了《无人驾驶实战》课程&#xff0c;老师讲的真好。好记性不如烂笔头&#xff0c;记录一下学习内容。 ————————————————————————————————————————— 无人驾驶汽车的定义&#xff1a; 无人驾驶汽车是可载人的移动智能机器…

【ASP.NET MVC】动态与静态网站(3)

一、区别 静态网页&#xff08;站&#xff09; 用户通过浏览器提交访问需求&#xff0c;需求可以是默认首页或者指定的网站中的某个页面&#xff0c;WEB服务器查找对应的网页&#xff0c;通过HTTP协议发送到客户端&#xff0c;完成访问。 特点&#xff1a;每次访问、不同角色…

视频监控综合管理平台EasyCVR修改参数提示database or disk is full是什么原因?

EasyDarwin开源流媒体视频EasyCVR安防监控平台可提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、智能分析等能力。视频监控综合管理平台EasyCVR具备视频汇聚融合能力&#xff0c;平台基于云边端一体化架构&#xff0c;具有强大…

【MCU学习】GD32F427VG开发

&#xff08;一&#xff09;学习文档和例程 兆易创新GD32 MCU参考资料下载 1.GD232F4xx的Keil芯片支持包 2.标准固件库和示例程序 3.GD32F4xx_固件库使用指南_Rev1.2 4.用户手册&#xff1a;GD32F4xx_User_Manual_Rev2.8_CN 5.数据手册&#xff1a;GD32F427xx_Datasheet_Rev…

通信笔记——最小移频键控MSK

由2FSK→MSK存在以下几点&#xff1a; 1、如何实现已调信号的码元正交&#xff1b;2、如何实现相位连续&#xff0c;不突变。 1、以2FSK一般表示法出发&#xff0c;推导得出两种频率的约束关系 正交条件&#xff1a; 积化和差公式有&#xff1a; 当载波频率比较高&#xff…

类欧几里得算法学习笔记

偶然发现了学长发给我的一个学长的学长也是我的学长的一个数论 p p t ppt ppt&#xff0c;先不着急复习莫反杜教筛&#xff0c;按这个顺序来吧 0.随便说说 前一阵子确实学习状态不是很好&#xff0c;我感觉我个人学习状态也是忽好忽坏的&#xff0c;不过只要在学习状态好的时…

大麦链接源码 大麦一键生成订单截图

8.4最新版源码 更新了大麦链接模版 更新了大麦订单截图一键生成 下载源码&#xff1a;https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3

TM4C123的ROM函数和非ROM函数区别

前言 在开发TM4C123的时候&#xff0c;我看到ROM函数和非ROM函数。例如ROM_FPUEnable()和FPUEnable()函数&#xff0c;这两个就只是前缀不一样。有什么区别和不同&#xff1f; 相同点 ROM函数和非ROM函数的作用起始是一样的&#xff0c;比如上面的例子ROM_FPUEnable()和FPUEnab…

如何有效地扩展数据库服务器以满足日益增长的工作量

在当今以数据为驱动的世界中&#xff0c;企业面临着一个挑战&#xff0c;即在保证应用程序的最佳性能的同时&#xff0c;管理迅速增长的数据量。扩展数据库服务器在满足这些需求方面起着至关重要的作用。本篇博客将探讨各种策略&#xff0c;以有效地扩展数据库服务器&#xff0…

[C++]

C 一.C基础入门1.HelloWorld2.注释3.变量4.常量5.关键字6.命名规则 二.数据类型1.整形2.sizeof关键字3.浮点型4.字符型5.转义字符6.字符串型7.布尔类型8.数据的输入 三.运算符1.算数运算符2.赋值运算符3.比较运算符4.逻辑运算符 一.C基础入门 1.HelloWorld 首先到官网下载并安…

P2824 [HEOI2016/TJOI2016] 排序(线段树)(内附封面)

[HEOI2016/TJOI2016] 排序 题目描述 在 2016 2016 2016 年&#xff0c;佳媛姐姐喜欢上了数字序列。因而她经常研究关于序列的一些奇奇怪怪的问题&#xff0c;现在她在研究一个难题&#xff0c;需要你来帮助她。 这个难题是这样子的&#xff1a;给出一个 1 1 1 到 n n n 的…

关于单测技术选型,聊聊我的思考

对于单测来说&#xff0c;目前常用的单测框架有&#xff1a; JUnitMockitoSpockPowerMockJMockitTestableMock 其中 JUnit 不支持 Mock&#xff0c;因此基本不会只用 JUnit&#xff0c;而是结合其他有 Mock 功能的框架一起使用。从知名度及使用率来说&#xff0c;Mockito 和 …

【基于HBase和ElasticSearch构建大数据实时检索项目】

基于HBase和ElasticSearch构建大数据实时检索项目 一、项目说明二、环境搭建三、编写程序四、测试流程 一、项目说明 利用HBase存储海量数据&#xff0c;解决海量数据存储和实时更新查询的问题&#xff1b;利用ElasticSearch作为HBase索引&#xff0c;加快大数据集中实时查询数…

干就完了

&#xff08;1&#xff09; ENIAC诞生于1946年。但安达信在1954年就拿计算机给通用电气公司算薪&#xff0c;这算计算机最早在工商业界的应用。 其实算薪这个事吧&#xff0c;严格意义来说是人力服务的BPO&#xff0c;只不过为了让这个算薪BPO项目更高效率更高质量更低成本地完…

无人机巢的作用及应用领域解析

无人机巢作为无人机领域的创新设备&#xff0c;不仅可以实现无人机的自主充电和电池交换&#xff0c;还为无人机提供安全便捷的存放空间。为了帮助大家更好地了解无人机巢&#xff0c;本文将着重解析无人机巢的作用和应用领域。 一、无人机巢的作用 无人机巢作为无人机技术的重…

模型优化调参方法介绍(Python代码)

模型算法在机器学习和深度学习中都发挥着自己的作用&#xff0c;但往往训练出来的模型效果不佳或稳定性不强&#xff0c;就需要对模型进行调优。一般来说&#xff0c;会从以下几个角度来优化模型。 1.优化数据维度 在需要对原始需求进行理解、准确定义好坏样本的前提下&#…

MySQL第六七弹,自连接等复杂查询,索引部分知识

一、&#x1f49b; 自连接&#xff1a;自己和自己笛卡尔积&#xff08;奇淫巧技&#xff0c;特殊场景很牛逼&#xff09; SQL&#xff1a;编写条件都是列和列之间的比较&#xff0c;但是SQL无法进行&#xff0c;行与行之间的比较。 如&#xff1a;显示所有java比计算机原理高的…

中电金信杜啸争:逐“数”兴业,智胜未来

在数字化转型大潮中&#xff0c;数据要素市场未来如何发展&#xff1f;作为天然具有大量数据应用场景和需求的金融行业&#xff0c;能否逐“数”兴业&#xff0c;实现“换道超车”&#xff1f; 本期分享由中电金信商业分析事业部总经理&#xff0c;中电金信数据研发委员会主席…