不得不感慨巨硬家的服务,一般的解决方案啥都做好了,如果一个项目从头开始,配置来配置去还是要成为它们家解决方案的样子。
控制台应用程序 解决方案目前是没有自带配置文件功能的,如果要使用配置文件,就要自己去实现那一套。好就好在底层已经有了,我们只要经过简单的配置就可以实现了。
创建项目
使用 Visual Studio 或 Visual Studio Code 创建一个名为 loadconfig
的 控制台应用程序。
如果你习惯使用命令行,像我一样,也可以运行下面的命令来创建
dotnet new console --name loadconfig
创建完成后,项目目录一般如下
├── Program.cs ├── loadconfig.csproj └── obj ├── loadconfig.csproj.nuget.dgspec.json ├── loadconfig.csproj.nuget.g.props ├── loadconfig.csproj.nuget.g.targets ├── project.assets.json └── project.nuget.cache
目录长啥样,不重要,主要的里面得有个 Program.cs
文件,如果实在没有,那么就自己创建一个吧
加载必要的扩展
需要使用配置文件功能,我们就需要先添加一些扩展,还挺多的,我列在下面了
扩展 | 描述 |
---|---|
Microsoft.Extensions.Configuration |
配置文件所需的基础包,包含 IConfiguration 和 Configuration 构建器 (Builder) |
Microsoft.Extensions.Configuration.Json |
如果配置文件是 .json 格式,则需要该扩展 |
Microsoft.Extensions.Configuration.CommandLine |
如果要支持控制台或命令行传递参数,则需要该扩展 |
Microsoft.Extensions.Configuration.EnvironmentVariables |
如果需要环境变量来设置参数,则需要该扩展 |
Microsoft.Extensions.Configuration.Binder |
如果要使用类来绑定配置变量则需要该扩展 |
简单的说,Microsoft.Extensions.Configuration
扩展是必须的,其它则看项目的情况。
Install-Package Microsoft.Extensions.Configuration Install-Package Microsoft.Extensions.Configuration.Binder Install-Package Microsoft.Extensions.Configuration.Json Install-Package Microsoft.Extensions.Configuration.CommandLine Install-Package Microsoft.Extensions.Configuration.EnvironmentVariables
如果你习惯使用命令行,也可以使用下面的命令添加
dotnet add package Microsoft.Extensions.Configuration dotnet add package Microsoft.Extensions.Configuration.Binder dotnet add package Microsoft.Extensions.Configuration.Json dotnet add package Microsoft.Extensions.Configuration.CommandLine dotnet add package Microsoft.Extensions.Configuration.EnvironmentVariables
引入命名空间
好了,接下来我们可以开始要写代码了,第一步就是引入命名空间。当然了,如果你使用的是 Visual Studio 或者 Visual Studio Code 且配置了自动完成功能,那么这一步就省略吧。但是像我这样使用 Sublime Text 4 的人,还是老老实实的先引入
using Microsoft.Extensions.Configuration;
对,其实只需要引入这个命名空间即可,因为其它的命令空间都是默认使用的,不需要我们导入
创建配置文件
在项目的根目录下新建一个 应用设置文件 类型的文件,名字我们就使用默认的 appsettings
即可。 这其实是一个 .json
文件。 如果你使用的是 Visual Studio 或 Visual Studio Code 那么已经有默认的内容了
{ "ConnectionStrings": { "DefaultConnection": "DataSource=app.db" }, "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*" }
恩,我们什么都不做修改,就这样吧。如果你使用的是命令行,那么直接 touch appsettings.json
然后把上面的内容拷贝进去即可。
.NET Core 配置文件原理
ASP.NET Core 的 应用设置文件 有两个比较重要的概念 段(Section) 和 项(Item) 。段和项之间的关系,就像命名空间和类之间的关系一样。
段 Section
段(Section) 有点类似命名空间,就像上面的 Logging
和 ConnectionStrings
和 LogLevel
。
段 支持多级嵌套,段里面可以包含零个或多个项。
项 Item
项(Item) 是一个 键值对,使用 冒号 拼接键和值。就像上面的 "AllowedHosts": "*"
和 "Default": "Warning"
。
项可以在包含一个 段 里面,比如 "Default": "Warning"
,也可以没有段来包含,比如 "AllowedHosts": "*"
,如果没有段包含,则使用默认的段 Default
,但这不是必须的。
Default 这个名字还有待商量,我还没去翻源码。
使用配置文件的流程
-
使用类
ConfigurationBuilder
创建一个配置文件构建器。IConfigurationBuilder buider = new ConfigurationBuilder();
-
调用构建器的
AddJsonFile()
方法加载 应用配置文件,也就是.json
配置文件。buider.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
这个方法呢,最重要的是 reloadOnChange
参数,如果设置为 true
,则会监控该配置文件,如果配置文件变更则会重新载入。
optional
如果设置为 false
,当配置文件不存在时,则会报错
这步不是必须的,如果你不使用应用配置文件,那么就不用调用这个方法。
-
如果你还需要载入环境变量等,则可以调用构建器的
AddEnvironmentVariables()
方法。buider.AddEnvironmentVariables();
-
如果你还需要命名行传递参数,则可以调用构建器的
builder.AddCommandLine()
方法。builder.AddCommandLine(args);
这个方法的参数必须要传递 Main()
方法的 args
参数。
- 好了,最后调用构建器的
.Build()
方法创建IConfiguration config = builder.Build();
获取配置项
配置文件加载完成后,我们就可以调用 IConfiguration
配置实例提供的 GetSection()
方法获取 段,或调用 Configuration.GetValue()
获取 项。
var section = config.GetSection("ConnectionStrings"); var allowedHosts = config.GetValue<string>("AllowedHosts");
我们还可以获取 段中的段
var logging = config.GetSection("Logging"); var logLevel = config.GetSection("LogLevel");
还可以获取段中的 项
var section = config.GetSection("ConnectionStrings"); var defaultConnection = section.GetValue<string>("DefaultConnection");
将段绑定到实例
我们还可以将某个段绑定到某个实例上。
首先我们创建一个日志类
public class ConnectionConfig { public string DefaultConnection { get; set; } } var connectConfig = new ConnectionConfig(); section.Bind(connectConfig); Console.WriteLine($"ConnectionConfig:{connectConfig.DefaultConnection}");
完整的代码
using System; using Microsoft.Extensions.Configuration; namespace loadconfig { class Program { static void Main(string[] args) { // 1. 创建一个配置文件构建器 IConfigurationBuilder builder = new ConfigurationBuilder(); // 2. 载入 .json 格式的配置文件,`reloadOnChange` 参数决定了配置文件变更后是否重新载入 builder = builder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); // 3. 载入环境变量 builder = builder.AddEnvironmentVariables(); // 4. 载入命令行参数 builder = builder.AddCommandLine(args); // 5. 生成 Configuration 配置实例 IConfiguration config = builder.Build(); Console.WriteLine(config); // 6. 获取段 var section = config.GetSection("ConnectionStrings"); // 7. 获取节 var allowedHosts = config.GetValue<string>("AllowedHosts"); Console.WriteLine($"AllowedHosts:{allowedHosts}"); // 8. 获取段中的段 var logging = config.GetSection("Logging"); var logLevel = config.GetSection("LogLevel"); // 9. 获取段中的项 var defaultConnection = section.GetValue<string>("DefaultConnection"); // 11. 首先创建配置类的实例 var connectConfig = new ConnectionConfig(); section.Bind(connectConfig); Console.WriteLine($"ConnectionConfig:{connectConfig.DefaultConnection}"); } } // 10. 创建一个配置类 public class ConnectionConfig { public string DefaultConnection { get; set; } } }
常见问题
如果运行的时候出现如下错误
Unhandled exception. System.IO.FileNotFoundException: The configuration file 'appsettings.json' was not found and is not optional. The expected physical path was '/Users/xxx/loadconfig/bin/Debug/net5.0/appsettings.json'.
那是因为 appsettings.json
并没有拷贝到运行时目录,解决办法有两个,一个是将 appsettings.json
改成绝对路径,比如
builder = builder.AddJsonFile("/Users/xxx/loadconfig/appsettings.json", optional: false, reloadOnChange: true);
另一个就是就是将我们的 appsettings.json
复制到输出目录,编辑 .csproj
文件,在 Project
中添加如下代码
<ItemGroup> <None Update="appsettings.json"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup>
如果你使用 Visual Studio,则可以
在 appsettings.json
上点右键,然后选择 快捷属性 -> 复制到输出目录