NET CORE Configuraion 使用详解

news2024/12/23 21:01:30

相关配置

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<OutputType>Exe</OutputType>
		<TargetFramework>netcoreapp3.1</TargetFramework>
	</PropertyGroup>

	<ItemGroup>
		<!--读取配置的核心包-->
		<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.0" />
		<!--Json中提取配置-->
		<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.0" />
		<!--Xml中提取配置-->
		<PackageReference Include="Microsoft.Extensions.Configuration.Xml" Version="3.1.0" />
		<!--Ini中提取配置-->
		<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="3.1.0" />
		<!--环境变量中提取配置-->
		<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.1.0" />
		<!--命令行中提取配置-->
		<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="3.1.0" />
		<!--依赖注入-->
		<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.0" />

		<!--将配置数据绑定到对象的相关引用-->
		<PackageReference Include="Microsoft.Extensions.Options" Version="3.1.0" />
		<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.0" />
		
	</ItemGroup>

	<ItemGroup>
	  <None Update="tsconfig.ini">
	    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  </None>
	  <None Update="tsconfig.json">
	    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
	  </None>
	  <None Update="tsconfig.xml">
	    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  </None>
	</ItemGroup>

</Project>
//tsconfig.dev.json
{
  "ConnectionStrings": {
    "db1": "dev_xx1,xx",
    "db2": "dev_xx2,xx"
  },
  "t1": {
    "t2": {
      "t3": "dev_t1_t2_t3_val"
    }
  },
  "c1": {
    "c2": "dev_c1_c2_val"
  },
  "d1": {
    "d2": "dev_d1_d2_val"
  }
}


//tsconfig.json
{
  "ConnectionStrings": {
    "db1": "xx1,xx",
    "db2": "xx2,xx"
  },
  "t1": {
    "t2": {
      "t3": "t1_t2_t3_val"
    }
  },
  "c1": {
    "c2": "c1_c2_val"
  },
  "d1": {
    "d2": "d1_d2_val"
  }
}


//tsconfig.ini
MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning


//tsconfig.xml
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<MyKey>MyXMLFile Value</MyKey>
	<Position>
		<Title>Title from  MyXMLFile</Title>
		<Name>Name from MyXMLFile</Name>
	</Position>
	<Logging>
		<LogLevel>
			<Default>Information</Default>
			<Microsoft>Warning</Microsoft>
		</LogLevel>
	</Logging>
</configuration>

读取环境变量

引用:

<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.1.0" />
ConfigurationBuilder configBuilder = new ConfigurationBuilder();
configBuilder.AddEnvironmentVariables(prefix: "test_");
var config = configBuilder.Build();
//读取test_p1环境变量的值,这里不需要【test_】前缀
var p1 = config["p1"];
Console.WriteLine($"test_1:{p1}");

运行结果 :

 

示例代码说明:

1、test_ 前缀的环境变量会被加载到程序,如果没有前缀会加载所有环境变量。
2、需要注意的是,在读取环境变量时不需要前缀。
3、DOTNET_ 和 ASPNETCORE_ 前缀会由 ASP.NET Core 用于主机和应用配置,但不用于用户配置,详细介绍可以参考:https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-7.0

读取配置文件 

注意:需要设置tsconfig.json文件的属性为【如果较新则复制】或【者始终复制】 

ConfigurationBuilder configBuilder = new ConfigurationBuilder();
/*
 optional:参数表示这个文件是否可选,如果它的值为true,则当配置文件不存在的时候,程序不会报错;如果它的值为false,当配置文件不存在的时候,程序会报错
 eloadOnChange:参数表示如果文件修改了,是否重新加载配置
 */
configBuilder.AddJsonFile("tsconfig.json", optional: false, reloadOnChange: false);
IConfigurationRoot config = configBuilder.Build();

//获取连接字符串,读取“ConnectionStrings”节点下的名为【db2】的连接字符串值
var conn = config.GetConnectionString("db2");
Console.WriteLine($"conn:{conn}");

string value = config.GetSection("t1:t2:t3").Value;
Console.WriteLine($"value={value}");

 运行结果:

读取Ini配置

ConfigurationBuilder configBuilder = new ConfigurationBuilder();
configBuilder.AddEnvironmentVariables(prefix: "test_");
configBuilder.AddIniFile("tsconfig.ini", optional: false, reloadOnChange: false);
IConfigurationRoot config = configBuilder.Build();
var myKeyValue = config["MyKey"];
var title = config["Position:Title"];
var positionName = config["Position:Name"];
var defaultLogLevel = config["Logging:LogLevel:Default"];
Console.WriteLine($"MyKey value: {myKeyValue} \n" +
               $"Title: {title} \n" +
               $"Name: {positionName} \n" +
               $"Default Log Level: {defaultLogLevel}");

 运行结果:

 读取Xml配置

ConfigurationBuilder configBuilder = new ConfigurationBuilder();
configBuilder.AddEnvironmentVariables(prefix: "test_");
configBuilder.AddXmlFile("tsconfig.xml", optional: false, reloadOnChange: false);
IConfigurationRoot config = configBuilder.Build();
var myKeyValue = config["MyKey"];
var title = config["Position:Title"];
var positionName = config["Position:Name"];
var defaultLogLevel = config["Logging:LogLevel:Default"];
Console.WriteLine($"MyKey value: {myKeyValue} \n" +
               $"Title: {title} \n" +
               $"Name: {positionName} \n" +
               $"Default Log Level: {defaultLogLevel}");

 运行结果:

 使用选项方式读取配置

//注意:reloadOnChange 需要设置为true
ConfigurationBuilder configBuilder = new ConfigurationBuilder();
configBuilder.AddJsonFile("tsconfig.json", optional: false, reloadOnChange: true);
IConfigurationRoot config = configBuilder.Build();
//配置依赖注入
IServiceCollection services = new ServiceCollection();
services.AddOptions().Configure<OptionConnectionStrings>(c => config.GetSection("ConnectionStrings").Bind(c));
services.AddTransient<Demo>();
using (var sp = services.BuildServiceProvider())
{
    while (true)
    {
        using (var scope = sp.CreateScope())
        {
            var spScope = scope.ServiceProvider;
            var demo = spScope.GetRequiredService<Demo>();
            demo.Test();
        }
        Console.WriteLine("可以改配置啦");
        Console.ReadKey();
    }
}


public class Demo
{
    /*
     1、IOptions<T>在配置改变后,我们不能读到新的值,必须重启程序才可以读到新的值;
     2、IOptionsMonitor<T>在配置改变后,我们能读到新的值;
     3、IOptionsSnapshot<T>也是在配置改变后,我们能读到新的值,和IOptionsMonitor<T>不同的是,在同一个范围内IOptionsMonitor<T>会保持一致性。
        通俗地说,在一个范围内,如果有A、B两处代码都读取了某个配置项,在运行A之后且在运行B之前,这个配置项改变了,那么如果我们用IOptionsMonitor<T>读取配置,
        在A处读到的将会是旧值,而在B处读到的是新值;如果我们用IOptionsSnapshot<T>读取配置,在A处和B处读到的都是旧值,只有再次进入这个范围才会读到新值
     */
    //private readonly IOptions<OptionConnectionStrings> optDbSettings;
    //private readonly IOptionsMonitor<OptionConnectionStrings> optDbSettings;
    private readonly IOptionsSnapshot<OptionConnectionStrings> optDbSettings;
    
    public Demo(IOptionsSnapshot<OptionConnectionStrings> optDbSettings)
    {
        this.optDbSettings = optDbSettings;
    }
    public void Test()
    {
        var db = optDbSettings.Value;
        Console.WriteLine($"数据库:{db.db1},{db.db2}");
    }
}

 第一次运行和修改配置文件后运行结果:

 命令行读取配置

ConfigurationBuilder configBuilder = new ConfigurationBuilder();
configBuilder.AddCommandLine(args);
IConfigurationRoot config = configBuilder.Build();
/*
 这里所用“:”号分层,对应json 格式为:
 {
     "t1":{
         "t2":{
             "t3":"t1_t2_t3_val"
         }
     }
 }
 */
string server = config["t1:t2:t3"];
Console.WriteLine($"value:{server}");

 运行结果:

 多源配置读取顺序分析

配置顺序如下:

 1、配置文件
 2、环境变量
 3、命令行            
 结论:后添加的配置提供程序中的配置覆盖会之前的配置

ConfigurationBuilder configBuilder = new ConfigurationBuilder();
configBuilder
    .AddJsonFile("tsconfig.json", optional: false, reloadOnChange: true)
    .AddJsonFile("tsconfig.dev.json", optional: false, reloadOnChange: true)
    .AddEnvironmentVariables()
    .AddCommandLine(args);
    
IConfigurationRoot config = configBuilder.Build();
Console.WriteLine($"t1:t2:t3={config["t1:t2:t3"]}\r\n" +
    $"c1:c2={config["c1:c2"]}\r\n" +
    $"d1:d2={config["d1:d2"]}\r\n" +
    $"ConnectionStrings:db1={config["ConnectionStrings:db1"]}");

运行结果: 

红色字体代表最终的输出结果: 

添加顺序ConnectionStrings:db1t1:t2:t3c1:c2d1:d2
dev.json配置文件dev_xx1,xxdev_t1_t2_t3_valdev_c1_c2_valdev_d1_d2_val
json配置文件xx1,xxt1_t2_t3_valc1_c2_vald1_d2_val
环境变量s_c1_c2_vals_d1_d2_val
命令行m_t1_t2_t3_valm_d1_d2_val

参考:

 【.NET Core框架】配置(Configuration) - .Neterr - 博客园

ASP.NET Core 中的配置 | Microsoft Learn 

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

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

相关文章

谷歌浏览器自定义标签页 newtab

创建一个文件夹, 里面放置信息: 其中&#xff0c; manifest.json 不能变&#xff0c; home.html 是新的标签页信息 manifest.json 内容: {"chrome_url_overrides": {"newtab": "home.html"},"manifest_version": 2,"name"…

新知实验室TRTC 初体验

引言 随着短视频行业的不断发展&#xff0c;人们对实时音视频的需求越来越多。在线直播&#xff08;秀场直播、电商直播、赛事直播、新品发布会、路演、在线拍卖&#xff09;的相关产品不断涌现&#xff0c;百花齐放。对于业务来说&#xff0c;自研开发一个实时音视频服务&…

spring boot 过滤器拦截器与aop

目录 一、过滤器 (Filter) 1.1 什么是过滤器 1.2 springboot配置过滤器 方式一&#xff1a;使用WebFilter 二、拦截器(Interceptor) 2.1 什么是拦截器 2.2 使用拦截器方法 三、拦截器&过滤器与spring aop的区别 3.1 区别 3.2添加aop 适用场景&#xff1a; 拦截…

Vue3中jsx父子传值、provide和inject、v-memo指令、Teleport内置组件、KeepAlive缓存组件、transition过渡组件

文章目录1. jsx父子传值2. provide和inject3. v-memo指令4. Teleport内置组件5. KeepAlive缓存组件6. transition过渡组件1. jsx父子传值 父组件&#xff1a; <template><div><child :title"title" :setTitle"setTitle" /></div>…

GitHub下载量过百万,阿里P8秘密分享的「亿级并发系统设计」真香

随着互联网的不断发展&#xff0c;CPU硬件的核心数也在不断进步&#xff0c;并发编程越来越普及&#xff0c;但是并发编程并不像其他业务那样直接了当。在编写并发程序时&#xff0c;我们常常都会出现各种漏洞&#xff0c;这些问题往往都突然出现&#xff0c;然后又迅速消失&am…

Java编码与解码

首先区分加密与编码并不是一回事&#xff0c; 本节主要讲述常见的三种编解码方式&#xff0c;分别为&#xff1a;Unicode、URL、Base64。 常见编码算法&#xff1a; Unicode编码&#xff1a;每一字符都可变成以 \u 开头&#xff0c;长度为6的字符串。URL编码&#xff1a;以百分…

Java并发编程--多线程间的同步控制和通信

使用多线程并发处理&#xff0c;目的是为了让程序更充分地利用CPU &#xff0c;好能加快程序的处理速度和用户体验。如果每个线程各自处理的部分互不相干&#xff0c;那真是极好的&#xff0c;我们在程序主线程要做的同步控制最多也就是等待几个工作线程的执行完毕&#xff0c;…

JS表达式完全攻略

在语法概念中&#xff0c;运算符属于词&#xff0c;表达式属于短语。表达式由一个或多个运算符、操作数组成的运算式。表达式的功能是执行计算&#xff0c;并返回一个值。 表达式的形式 表达式是一个比较富有弹性的运算单元。简单的表达式就是一个直接量、常量或变量。例如&a…

【优化调度】粒子群算法求解水火电调度优化问题【含Matlab源码 1181期】

⛄一、粒子群算法简介 1 引言 自然界中的鸟群和鱼群的群体行为一直是科学家的研究兴趣所在。生物学家Craig Reynolds在1987年提出了一个非常有影响的鸟群聚集模型&#xff0c;在他的仿真中&#xff0c;每一个个体都遵循&#xff1a;避免与邻域个体相撞&#xff1a;匹配邻域个体…

Java面向对象之——封装

文章目录前言一、封装的概念二、何为封装&#xff1f;三、封装拓展——包&#x1f351;1、包的概念&#x1f351;2、导入包中的类&#x1f351;3、自定义包&#x1f351;4、常见的包四、访问限定符&#x1f351;1、public修饰符&#x1f351;2、private修饰符&#x1f351;3、默…

软件产品确认测试包括哪些方面

1.技术方面 确认测试又称有效性测试&#xff0c;是在模拟的环境下&#xff0c;运用黑盒测试的方法&#xff0c;验证被测软件是否满足需求规格说明书列出的需求。 确认测试的目的是向未来的用户表明系统能够像预定要求那样工作。经集成测试后&#xff0c;已经按照设计把所有的模…

Docker 下 jitsi-meet 视频服务器 安装部署

一、参考网站 官网文档地址&#xff1a;Self-Hosting Guide - Docker | Jitsi Meet 二、Docker 版本 三、安装部署 3.1、下载并解压缩安装包 地址&#xff1a;Release stable-8044: release jitsi/docker-jitsi-meet GitHub CSDN地址&#xff1a;docker-jitsi-meet-stab…

visdom安装及使用

目录1. 安装visdom的流程2. 使用流程1. 安装visdom的流程 重点参考链接&#xff1a;visdom安装出现Downloading scripts, this may take a little while然后就不动了 先去到github直接下载了visdom的压缩包&#xff1a;https://github.com/fossasia/visdom然后将visdom-maste…

第七章 数学 6 AcWing 1593. 整数分解

第七章 数学 6 AcWing 1593. 整数分解 原题链接 AcWing 1593. 整数分解 算法标签 数学 数论 DP 背包问题 思路 类似AcWing 12. 背包问题求具体方案 把n看成背包的容积N 因为n最多不超过400&#xff0c;然而p进制最少为2 所以物品的价值最大可以取到20(因为20^2 400) 所以…

Python读取CSV文件,数值精度丢失

Excel保存为csv以后&#xff0c;大数值的列&#xff0c;会把转换为科学计数法&#xff0c;而且后边几位都会被转为0. 搞了很多方法,最后直接安装 openpyxl 组件 和 pandas&#xff0c; 读取Excel文件就行了。 data pd.read_excel("C:/work/20221111AI/cleaned_data_noTi…

第二章 计算机算术

数据表示决定了计算机所执行操作的类型&#xff0c;数据从一个位置传到另一个位置的方法&#xff0c; 以及对存储元件的特性要求。浮点运算是非常重要的&#xff0c;因为它的实现决定了计算机执行复杂图形变换和图像处理的速度&#xff0c; 而且浮点运算对计算的准确度也有很重…

高通平台开发系列讲解(mm-camera篇)MM-CAMERA框架

文章目录 一、Camera软件位置1.1、开源代码1.2、专有源码二、摄像头前端(Camera Frontend)2.1、整体框架2.2、 Camera HAL与mm-camera交互沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章主要介绍高通平台mm-camera代码框架。 一、Camera软件位置 QTI 针对 An…

Flink 状态编程

状态编程有状态算子状态的管理状态的分类按键分区状态&#xff08;Keyed State&#xff09;支持的结构类型代码实现状态生存时间&#xff08;TTL&#xff09;算子状态&#xff08;Operator State&#xff09;基本概念和特点状态类型代码实现广播状态&#xff08;Broadcast Stat…

DFP 数据转发协议应用实例 .与其它厂商 LoRA 设备匹配

DFP 数据转发协议应用实例 5.与其它厂商 LoRA 设备匹配 DFP 是什么&#xff1f; 稳控科技编写的一套数据转发规则&#xff0c; 取自“自由转发协议 FFP&#xff08;Free Forward Protocol&#xff09;” &#xff0c;或者 DFP&#xff08;DoubleF Protocol&#xff09;&#xf…