- 原文地址:Why, Where, and How of .NET Configuration Files
- 原文作者:Eric Lynch
- 译文出自:掘金翻译计划
.Net 配置文件概览
本文提供了 .NET 配置文件的快速概览,及了解更深入信息的链接。
更新:世界一直在前进。本文中的大部分信息现已过时。首选的配置机制现在位于 NuGet 的 Microsoft.Extensions.Configuration 及相关包中。有关更多的详细内容,请参阅此链接中的 ConfigurationBuilder 类的文档。
介绍
已经使用 .NET 配置文件很多年了,如果我能够提供一个有关的快速介绍,可能会给别人带来很大帮助。
在本文中,有许多的 C# 代码示例,假设您在项目中包含了对 System.Configuration.dll 的引用,并且在代码中添加了以下 using 语句:
using System.Configuration;
要想使用可以访问配置信息的 ConfigurationManager 类,必须满足这两个前提条件。
为什么
.NET Framework 提供了一组丰富的类和技术来简化应用程序的配置。本质上,所有的这些类都使从 XML 配置文件读取和写入配置信息变得更容易。
配置文件包括许多标准的节(译注:section,通常在配置文件中一个配置项表示一个section,在翻译习惯上通常称为“节”),用于常见 .NET 功能的自定义节,以及允许开发人员创建自己的自定义配置节。
标准节随着时间的推移而一直发生着改变。最初,标椎配置主要通过 appSettings 节完成,包含了每个设置的 name/value 对。而后来,通过生成的 C# Settings 类,及对应的 applicationSettings 和 userSettings 配置节,向配置提供了透明、类型安全的支持。
在哪(存储位置)
在哪可以发现配置文件?这是一个看似很复杂的问题。由于配置是分层的,所以可能会有多个配置文件影响一个应用程序。其中包括机器配置文件、应用(或web)配置文件、用户本地设置文件和用户漫游设置文件。
机器配置
机器配置文件与不太容易找到的 .NET Framework 文件放在一起。配置文件的位置取决于应用程序使用的 .NET 版本和平台类型(例如 64 位)。
一个典型的示例,可能是 C:\Windows\Microsoft.NET\Framework\v4.0.30319\CONFIG\machine.config。
在 C# 应用程序中,下面的代码可以返回该文件的位置:
System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
+ @"CONFIG\machine.config"
应用程序配置
应用程序配置文件通常与应用程序位于同一目录中。对于 Web 应用程序,它被命名为 Web.config。对于非 Web 应用程序,开始的名称是 App.config 。在构建之后,它被复制为与 .exe 文件相同的名称。因此,对于程序 MyProgram.exe,你可以在同一目录中找到 MyProgram.exe.config。
在 C# 应用程序中,下面的代码可以返回该文件的位置:
AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
然而通常不建议这样做,因为,你可能会发现某些程序更改了应用程序配置文件的位置,如下所示:
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "NewName.config")
用户设置
用户设置文件几乎不可能找到,也许是故意这样设计的。其目录的名称因 Windows 版本而异。更复杂的是,父文件夹通常是隐藏的。文件夹目录中还包含公司名称(应用程序供应商)、应用程序名称、应用程序的唯一标识和应用程序版本。
一个 Windows 7 上关于本地用户设置的示例可能是这样的:
C:\Users\MyUsername\AppData\Local\CompanyName\MyProgram.exe_Url_pnbmzrpiumd43n0cw05z2h4o23fdxzkn\1.0.0.0\user.config
在下面的 C# 代码中,你可以获取本地用户设置(第一行)和漫游用户设置(第二行)的基目录:
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
在如下的 C# 代码中,可以获得本地用户设置(第一行)和漫游用户设置(第二行)的确切文件路径:
ConfigurationManager.OpenExeConfiguration
(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoaming).FilePath
其他配置
如果这还不够令人困惑,还可以了解一些其他文件。比如根级别的 Web.config(位于与 machine.config 相同的目录中)。此外,Web 应用程序的子目录可以通过特定于该子目录的 Web.config ,对继承的设置进行额外重写。
最后,IIS 提供了一些它自己的配置。典型的位置是:C:\Windows\System32\inetsrv\ApplicationHost.config。
如何使用
如之前所述,应用程序配置文件被分成许多类似标准的配置节。在这里,我们简要讨论一些最常见的配置节。
appSettings 节
最简单的标准配置节是 appSettings,包含每个设置对应的 name/value 对的集合:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="MySetting" value="MySettingValue" />
</appSettings>
</configuration>
在 C# 中,可以使用如下方式引用设置的值:
string mySetting = ConfigurationManager.AppSettings["MySetting"];
connectionStrings 节
由于数据库连接在 .NET 中非常常见,因此为数据库连接字符串提供了一个特殊的配置节,即 connectionStrings:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="MyConnectionStringName"
connectionString="Data Source=localhost;Initial Catalog=MyDatabase;
Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
在 C# 中,可以使用如下代码获取连接字符串:
string connectionString = ConfigurationManager.ConnectionStrings[
"MyConnectionStringName"].ConnectionString;
最初,人们可能不知道是否需要引用“连接字符串”的 ConnectionString 属性。实际 connectionStrings 节的名称很糟糕。更好的名称应该是 connectionStringSettings,因为每条记录都包含一个连接字符串和一个数据库提供程序。
连接字符串的语法完全由数据库提供程序决定。在本例中,System.Data.SqlClient 是 Microsoft SQL Server 数据库最常见的数据库提供程序。
applicationSettings 和 userSettings 节
在 .NET 2.0 中,Microsoft 试图使配置文件的使用变得更加容易。因此,引入了一个设置文件。细心的观察者会注意到,“设置”首先位于应用程序配置文件中,然后被复制到用户设置的配置文件里。
对于 Windows 窗体和 WPF 应用程序,可以在项目的 Properties 文件夹中找到一个 Settings.settings 文件。对于控制台和其他应用程序,同样可以使用这个设置。打开项目的属性,然后单击 设置 按钮/选项卡。将会看到添加默认设置文件的选项。
译者注,如下为项目“属性”-“设置”中添加默认设置文件的截图:
通常,只需编辑此设置文件(或项目的设置)而不是直接编辑配置文件。下面的示例仅用于演示这些设置确实存在于配置文件中。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings"
type="System.Configuration.UserSettingsGroup, System,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="WinFormConfigTest.Properties.Settings"
type="System.Configuration.ClientSettingsSection, System,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
allowExeDefinition="MachineToLocalUser"
requirePermission="false" />
</sectionGroup>
<sectionGroup name="applicationSettings"
type="System.Configuration.ApplicationSettingsGroup, System,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="WinFormConfigTest.Properties.Settings"
type="System.Configuration.ClientSettingsSection, System,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<WinFormConfigTest.Properties.Settings>
<setting name="MyUserSetting" serializeAs="String">
<value>MyUserSettingValue</value>
</setting>
</WinFormConfigTest.Properties.Settings>
</userSettings>
<applicationSettings>
<WinFormConfigTest.Properties.Settings>
<setting name="MyApplicationSetting" serializeAs="String">
<value>MyApplicationSettingValue</value>
</setting>
</WinFormConfigTest.Properties.Settings>
</applicationSettings>
</configuration>
要引用其中的设置项,只需使用自动创建的 Settings 类。如下所示是一个典型的参考:
string myUserSetting = Properties.Settings.Default.MyUserSetting;
string myApplicationSetting = Properties.Settings.Default.MyApplicationSetting;
注意:Properties 是在你的应用程序名的空间中自动创建的命名空间。
要改变用户的设置,只需给该属性指定一个值并保存更改,如下所示:
Properties.Settings.Default.MyUserSetting = newValueForMyUserSetting;
Properties.Settings.Default.Save();
更新设置
最后,还要发布应用程序的新版本。此时,你可能会遇到一个常见的问题。由于用户设置是特定于版本的,它们将会在升级后丢失。
值得庆幸的是,该框架预见到了这一需求并提供了升级方法。处理此问题的典型方式是用户设置的布尔值属性 Upgraded,初始值为 false(首次部署应用程序时)。
因此,处理升级(并保留以前的用户设置)的典型代码如下所示:
if (!Properties.Settings.Default.Upgraded)
{
Properties.Settings.Default.Upgrade();
Properties.Settings.Default.Upgraded = true;
Properties.Settings.Default.Save();
}
下一步是什么
在上一部分,你可能已经注意到配置文件中相当冗长的 configSections 节。这就是 Microsoft 扩展配置文件添加新的 userSettings 和 applicationSettings 节的方式。
这也是你可以添加你自己的自定义配置节的方式。
简而言之,你可以通过扩展 ConfigurationSection 和 ConfigurationElement 类来实现这一点。在每个派生类中,你将使用 ConfigurationPropertyAttribute 之类的属性来修饰成员。
简单吧?开个玩笑。其他人对这个稍微复杂但不太困难的机制提供了很好的描述。在本文的末尾提供了链接以供进一步阅读。
此处,我只想提供一些提示,这些提示可能会在较长的描述中被忽略。
全部完成后,你需要创建一个 XML 架构的文档(XML Schema Document —— XSD 文件)用于描述你的节,并将其包含在项目中。打开配置文件后,你可以使用 XML...Schemas 菜单项来确保智能提示找到 XSD 文件。
取决于 Visual Studio 的版本,你可能会听到有关配置节的 xmlns 属性的抱怨。如果你遇到了,这有一个简单的解决方案。我通常从我自己的中间类 XmlnsConfigurationSection 派生,而不是直接从 ConfigurationSection 派生。这使得问题不会出现。
using System.Configuration;
namespace Extras.Configuration
{
abstract public class XmlnsConfigurationSection : ConfigurationSection
{
[ConfigurationProperty("xmlns")]
public string Xmlns
{
get { return (string)this["xmlns"]; }
set { this["xmlns"] = value; }
}
}
}
深入阅读
- ASP.NET Configuration File Hierarchy and Inheritance
- Unraveling the Mysteries of .NET 2.0 Configuration
- Decoding the Mysteries of .NET 2.0 Configuration
- Cracking the Mysteries of .NET 2.0 Configuration
- System.Configuration Namespace
- ConfigurationSection Class
- ConfigurationElement Class
- ConfigurationPropertyAttribute Class
- ConfigurationElementCollection Class
