AppSettings与applicationSettings(.NET app.config / Web.config)的优缺点

174

在开发 .NET Windows Forms 应用程序时,我们可以选择使用 App.config 标签来存储配置值。哪一个更好呢?

<configuration>

  <!-- Choice 1 -->
  <appSettings>
    <add key="RequestTimeoutInMilliseconds" value="10000"/>
  </appSettings>

  <!-- Choice 2 -->
  <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c5612342342" >
        <section name="Project1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c5612342342" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <applicationSettings>
    <Project1.Properties.Settings>
      <setting name="TABLEA" serializeAs="String">
        <value>TABLEA</value>
      </setting>
    </Project1.Properties.Settings>
  </applicationSettings>

</configuration>

在微软的示例代码中,他们使用appSettings http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.aspx 我觉得这很令人困惑 :( - Hunt
1
发现了这篇文章http://www.codeproject.com/KB/files/SaveConnStringInAppConfig.aspx?q=working+with+applicationsettings+c%23,它似乎暗示appSettings用于读写,而applicationSettings仅用于只读。 - Hunt
另一篇相关的文章:https://dev59.com/F3RB5IYBdhLWcg3w9b59 - Hunt
请注意,同样适用于web.config文件,因此我将web.config标签添加到此问题中。 - Matt
6个回答

155
基本的<appSettings>比较简单,只需要添加一个<add key="...." value="..." />条目即可完成配置。

缺点是:没有类型检查,例如您不能安全地假设您要配置的数字确实是数字 - 某人可能会在该设置中输入字符串.....您只需通过ConfigurationManager["(key)"] 访问它,然后就取决于您了解自己正在处理什么。
此外,随着应用程序的不断增长,<appSettings>可能会变得相当混乱和杂乱无章,如果许多应用程序部分开始将内容放入其中(还记得旧的windows.ini文件吗?:-))。
如果可以的话,我建议使用自己的配置节-在.NET 2.0中,这变得非常容易。这样,您可以:
  • a) 在代码中定义配置设置并使其类型安全
  • b) 您可以将YOUR设置与其他所有设置清晰地分离开来。您还可以重复使用配置代码!
CodeProject上有一系列非常好的文章介绍如何揭开.NET 2.0配置系统的神秘面纱:
  1. 揭开.NET 2.0配置的神秘面纱
  2. 解码.NET 2.0配置的神秘之谜
  3. 破解.NET 2.0配置的谜题
强烈推荐! Jon Rista在解释.NET 2.0中的配置系统方面做得非常好。

2
我发现使用applicationSettings更容易添加、编辑和删除设置,而且你不需要编写一行代码,它们是类型安全的,而且你可以将它们作用于用户或应用程序,因为你只需要在VS中使用项目属性中的“设置”选项卡即可。 - markmnl

20

应用程序设置可以从设计器(通常默认情况下有一个Settings.settings文件)进行控制,因此更容易修改,并且您可以通过Settings类以编程方式访问它们,其中它们看起来像强类型属性。您还可以拥有应用程序级别和用户级别的设置,以及用于回滚的默认设置。

这在.NET 2.0及其以上版本中可用,并取代了其他做法(据我所知)。

更多详细信息请参见:msdn.microsoft.com/en-us/library/k4s6c3a0.aspx


16
为了理解app.config中设置的优点缺点,建议您深入了解两者的技术细节。我已经包含了一些链接,您可以在其中找到处理源代码以及更多技术细节的信息。
让我简要总结一下我在使用它们时所认识到的内容(注意:同样适用于网站/网络应用程序的web.config文件)。
.NET中的应用程序设置
(点击上面查看源代码和技术细节)

优点
  • 它们允许存储类型化数据,包括对象类型(通过serializeAs属性)

  • 它们具有用户和应用程序范围,允许存储默认值

  • 它们在Visual Studio的配置部分中得到支持

  • 非常好地支持长字符串和/或带特殊字符的数据(例如,包含双引号的嵌入式JSON字符串)


缺点

  • 用户设置存储在用户配置文件中的不同位置(具有加密路径),可能很难清理

  • 应用程序范围设置在应用程序运行时是只读的(仅用户范围设置可以在运行时更改)

  • 由Visual Studio的设置设计器构建的读/写方法代码,而不是由第三方工具直接提供的(请参见上面的链接以获取解决方法)


.NET中的AppSettings
更新:.NET Core中的AppSettings
(点击上面查看源代码和技术细节)


优点

  • “轻量级”,易于操作

  • 在应用程序运行时具有读写访问权限

  • 管理员可以轻松地在Internet Information Services (IIS) Manager中进行编辑
    (Features View -> 应用设置, 请注意图标名称会误导,因为它只能处理AppSettings而不是ApplicationSettings)


缺点

  • 仅支持字符串数据;字符串长度和特殊字符受限制。

  • 它们没有用户范围。

  • 它们不支持默认值。

  • 在 Visual Studio 的配置部分中不直接支持。



13

我之前找到一个模式,它使用基本的XML标签但将设置封装在静态配置类中。所以 - 一个DIY(自制)的App.Settings。

DotNetPearls Static Config Pattern

如果你这样做,你可以:

  • 对不同环境(开发、测试、生产)使用不同的配置值
  • 为每个设置提供合理的默认值
  • 控制如何定义和实例化数值

虽然设置过程很繁琐,但这种模式表现良好、隐藏了关键名称的引用并且是强类型的。这种模式适用于应用程序没有改变的配置,尽管你可能也可以支持更改。

配置:

<add key="machineName" value="Prod" />
<add key="anotherMachineName" value="Test" />
<add key="EnvTypeDefault" value="Dev" />

<add key="RootURLProd" value="http://domain.com/app/" />
<add key="RootURLTest" value="http://test.domain.com/app/" />
<add key="RootURLDev" value="http://localhost/app/" />

<add key="HumanReadableEnvTypeProd" value="" />
<add key="HumanReadableEnvTypeTest" value="Test Mode" />
<add key="HumanReadableEnvTypeDev" value="Development Mode" />

配置类:

using System;
using System.Collections.Generic;
using System.Web;
using WebConfig = System.Web.Configuration.WebConfigurationManager;

    public static class Config
    {
        #region Properties

        public static string EnvironmentType { get; private set; }

        public static Uri RootURL { get; private set; }

        public static string HumanReadableEnvType { get; private set; }

        #endregion

        #region CTOR

        /// <summary>
        /// Initializes all settings when the app spins up
        /// </summary>
        static Config()
        {
            // Init all settings here to prevent repeated NameValueCollection lookups
            // Can increase performance on high volume apps

            EnvironmentType =
                WebConfig.AppSettings[System.Environment.MachineName] ??
                "Dev";

            RootURL =
                new Uri(WebConfig.AppSettings["RootURL" + EnvironmentType]);

            HumanReadableEnvType =
                WebConfig.AppSettings["HumanReadableEnvType" + Config.EnvironmentType] ??
                string.Empty;
        }

        #endregion
    }

OP 想知道使用 A 还是 B 更好。我不明白 C 怎么可能是一个有效的答案。 - bkqc
@bkqc 我想我可以说“使用A并考虑封装它”。 - HAL9000
但它仍然不能解释A或B哪个更好,以及为什么,甚至更好的是,每个方案的利弊。 - bkqc

9

我喜欢使用更简单的版本来存储和访问单个值。

<appSettings>
    <add key="MyConfigKey" value="true"/>
</appSettings>

我编写了一个实用类,以类型安全的方式访问值,并允许设置默认值。如果未提供默认值,则会提供有用的异常信息。

您可以在此处查看/下载该类:

http://www.drewnoakes.com/code/util/app-settings-util/


3
+1,这样做更简单,特别是当你有多个程序集时(通常每个程序集都有一个设置部分)。我有一个类似的帮助类。顺便提一下,你的类目前期望配置文件使用与文化相关的字符串,这不是一个好习惯——例如应该使用"Double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out result)"而不是"Double.TryParse(s, out result)"。另外要挑剔一下,微软编码指南建议使用GetInt32、GetInt16和GetBoolean而不是GetInt、GetShort和GetBool。 - Joe
这很好,但并没有回答关于AppSettings的优缺点问题。 - Matt
@Matt,优点是它更简单。缺点也是它更简单。如果你只需要几个字面值(bools、ints、string等),那么这种方法可以在最小的代价下实现。如果您需要结构化数据、命名空间分离、XSD支持的验证/完成等,则自定义部分可能更适合。另一个选择是完全忽略App.config文件并使用自己的配置文件。许多库都这样做。NLog就是其中之一。 - Drew Noakes
@DrewNoakes - 我同意你的观点。感谢你的澄清。 - Matt

2
使用ApplicationSettings的一个重要优点是,当应用程序通过ClickOnce部署时,如此页面中所述,如果设置为用户类型并已从其默认值修改,则该设置将从更新到更新保持修改状态。如果设置为应用程序类型,则在更新应用程序时会自动覆盖。
此外,在VB.NET中,可以通过简单地使用My.Settings来访问ApplicationSettings,使它成为从GUI角度来看最简单的设置建议。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接