NET CORE Configuraion 使用详解 获取配置文件参数 读取环境变量、读取配置文件、读取Ini配置、读取Xml配置、多源配置读取顺序分析
https://blog.csdn.net/qq_32109957/article/details/127998326
相关配置
- <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:db1 | t1:t2:t3 | c1:c2 | d1:d2 |
dev.json配置文件 | dev_xx1,xx | dev_t1_t2_t3_val | dev_c1_c2_val | dev_d1_d2_val |
json配置文件 | xx1,xx | t1_t2_t3_val | c1_c2_val | d1_d2_val |
环境变量 | s_c1_c2_val | s_d1_d2_val | ||
命令行 | m_t1_t2_t3_val | m_d1_d2_val |
参考: