该项目旨在演示如何在新版的 DOTNET 项目中使用传统的 App.config
配合 ConfigurationManager
的方式管理配置项。
自 .NET Core 以来,诞生了新的 JSON 格式的配置方式,即 appsettings.json
,而不再推荐使用传统的 XML 格式的 App.config
。新的配置方式提供了更多新的功能,比如多个配置文件共存且存在优先级,以及获取环境变量等功能,这些都是传统方式不具备的。
但另一方面,传统方式提供了一套成熟的在运行时修改配置项并保存生效的机制,这也是新的方式不具备的;另外,传统方式还可以选择在程序根目录以外的位置(如用户目录下的存放程序缓存的路径)存放,从而区分不同的用户等,依旧存在自己的优势,所以并不能被新方法完全取代。
新版的 .NET 项目中,不再推荐使用 ConfigurationManager
来管理配置项,而是推荐使用 IConfiguration
接口。
另外,一些 .NET 新版本的一些新特性并不是很兼容传统的方式,尤其是发布单一文件(PublishSingleFile
),极有可能会导致 ConfigurationManager.OpenExeConfiguration()
方法无法顺利读取配置文件。
传统方式的配置项管理,主要有以下几个步骤:
- 在项目中添加
App.config
文件。无需关注该文件的生成操作(Build Action)以及是否复制到输出目录,因为它会自动被拷贝为输出目录中的ProjectName.dll.config
。 - 在
App.config
中添加符合格式要求的配置项。 - 在代码中使用
ConfigurationManager.OpenExeConfiguration()
方法读取配置项
当尝试发布为单一文件时,如果配置文件及配置项的读取并不发生在入口项目,此时上述读取配置项的方式会无法顺利找到 .config
配置文件。
发布指令如下:
dotnet publish -c Release -o publish -p:PublishSingleFile=true --self-contained false
此时有这么几种解决方案:
简单来说,只在入口项目中添加 App.config
文件,并在入口项目中通过 OpenExeConfiguration()
方法读取配置项,并生成 Configuration
实例,进而传参给其他方法。
具体可以查看 workaround
分支。
在发布时添加这一参数:
-p:IncludeAllContentForSelfExtract=true
可以使本应出现在输出目录的一些 .dll 以及 .config 文件被转移到用户目录下,例如 C:\Users\username\AppData\Local\Temp\AppName\
。
但这个方法并不推荐,因为这会导致配置文件不出现在应用程序的根目录,不利于管理。
参考:
这个方法可以指定配置文件的路径,从而避免了配置文件无法被找到的问题。
var map = new ExeConfigurationFileMap
{
ExeConfigFilename = "ConfigDemo.dll.config"
};
var config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
注意:OpenExeConfiguration()
方法也支持传入文件名,但并不能正确找到并读取配置项。这里只能通过 OpenMappedExeConfiguration
方法来实现。
参考: