【问题标题】:Where to store application settings?在哪里存储应用程序设置?
【发布时间】:2010-10-20 14:23:55
【问题描述】:

最近,我发现“Web.Config”文件包含一个<appSettings> 部分,这似乎很适合存储一个人的应用程序设置。哎呀,它甚至具有通过标准系统库访问文件的编程方式。所以很聪明,我写了一个接口来访问它,然后是一个接口的具体实现,如下所示:

public interface IAppSettings
{
    IEnumerable<string> GetValues(string componentName, string settingName);
    IEnumerable<KeyValuePair<string, string>> GetValuePairs(string componentName, string settingName);
    void SetValues(string componentName, string settingName, IEnumerable<string> valueList, bool append);
    void SetValuePairs(string componentName, string settingName, IEnumerable<KeyValuePair<string, string>> pairList, bool append);
}

然后我发现saving settings back to "web.config" while the application is running causes the entire application to re-start。这对我来说似乎完全不合理,因为如果我经常写回 web.config 并且应用程序每次都重新启动,那么 HttpRuntime.Cache 之类的东西就会被完全清空,从而使我的 Cache 无用,因为它一直在清空和重新填充。

所以我想知道:我应该将应用程序设置存储在哪里?

有没有一个很好的解决方案,这样我就不必自己动手了?

编辑:

好的,感谢所有建议使用数据库和潜在表架构的人。我想我将使用以下架构:

settings:
    index NUMBER NOT NULL AUTO_INCREMENT   <== Primary Key
    component NVARCHAR(255) NOT NULL
    setting NVARCHAR(255) NOT NULL
    key   NVARCHAR(255)
    value NVARCHAR(255) NOT NULL

虽然我不认为我会“设置” P-Key,而是使用自动增量索引。这样,如果我有一个应用程序需要向多个管理员发送邮件,我可以存储多个:

index     component       setting        value
1         RequestModule   ManagerEmail   manager1@someplace
2         RequestModule   ManagerEmail   manager2@someplace

然后我可以使用:

IEnumerable<string> GetValues(string componentName, string settingName);

它会返回一个电子邮件地址列表,而不仅仅是一个值。

这有意义吗?

【问题讨论】:

  • 使用 DB 存储应用程序设置是可以的,但请将设置存储在缓存中。 Web 配置中的设置可以快速阅读,因为它们位于服务器内存中。如果您经常阅读每个页面中的设置,请考虑将缓存添加到您的设置中,并在设置更新时从缓存中删除它们。
  • 在您编辑后,我编辑了我的答案。请注意,当您有两个问题时,请分别提出,而不是将第二个问题添加到前一个问题中。

标签: asp.net web-config appsettings application-settings


【解决方案1】:

web.config 一般用于只读设置,即。系统管理员在部署应用程序时设置的设置。

如果你想读写设置,最明显的方法是使用数据库。顺便说一句,这有一个优势:一个应用程序可以托管在多个服务器上,并且仍然可以正确读取和写入设置,

您还可以为设置实现自定义存储,但实现起来可能会更困难,而且速度不会快很多。


要回答您的第二个问题,您的数据库结构取决于您要存储的设置类型。

如果您需要像这样存储异构的唯一条目

  • 管理员的邮件地址,
  • 网站主页上显示的最大条目数,
  • 要在“关于我们”页面上显示的文字,
  • 布尔值,指示是否启用公共 cmets,

那么你必须使用varchars 或其他或多或少友好的类型作为键来识别条目(而不是通过它们的索引来引用它们)。

另一方面,如果您的目的是存储多个经理的邮件地址,您应该创建一个Manager 表,其中包含他们的邮件地址、姓名、上次连接的日期时间等.

您真的不应该将两者混用。理论上,您可以通过组件/设置对来参考设置中的条目。在实践中,它使事情变得更加困难并产生了一堆问题:

  • 如果您需要为每位经理存储一个布尔值,指示她/他是否希望接收您的警报,该怎么办?以您目前的结构,这是不可能的。
  • 由于同一设置可以有多个值,您打算如何处理必须唯一的设置?例如,“关于我们”页面上只能显示一个文本值。如果数据库中存储了两个值怎么办?

【讨论】:

  • 有趣,我没有考虑过可能在多个服务器上运行的应用程序,但这是有道理的。就我而言,它可能永远不会发生,因为它是针对公司内部项目的,但请记住这一点。
  • 有趣。我只是在寻找如何存储一个 single 值,因为启动一个只包含一条记录、一个整数的数据库表感觉不对。但是您说“web.config 通常用于只读设置”也是有道理的。由于您的(出色)回答,我很困惑在 Web 服务中存储应用程序范围的读/写整数的最佳位置在哪里。
【解决方案2】:

在 web.config 中存储设置很有用,因为它可以很容易地在不同的环境中进行不同的设置。但是,正如您所说,如果您可能想在实时环境中更改设置,这将毫无用处。

如果您需要更改值,一个简单的数据库表是最有用的方法。

例如。

create table Settings
(Name varchar(50) primary key,
Value varchar(50))

如果您使用的是 SQL Server,您可以将 Value 列设置为 sql_variant,这将允许您存储各种数据类型。

【讨论】:

  • +1 表示sql_variantnvarchar(max) 在存储任何类型的数据时都不是一个好主意(更不用说varchar(100))。
【解决方案3】:

它适用于应用程序设置,但不适用于在运行时动态更改的设置。相反,它适用于仅偶尔更改的设置,以及您希望(甚至希望)在更改时重新启动应用程序的位置。

对于更多临时设置,您可能只想使用简单的数据库系统 - 如果您的应用不使用数据库,即使 App_Data 目录中的平面文件/XML 也可以工作。

【讨论】:

    【解决方案4】:

    是的。更改 web.config 将重置应用程序。我通常维护一个设置表来存储设置的键值对并从那里访问它。

    设置

    SETTING_NAME   VARCHAR(100)PRIMARY KEY
    SETTING_VALUE  VARCHAR(100)
    

    然后编写一个可以插入,删除,更新该表的值的类。

    SETTINGS 表的 Ex 数据

        SETTING_NAME         SETTING_VALUE
    
        AdminEmail            admin@mysite.com
        ErrorTrackingEmail    errors@mysite.com
    

    【讨论】:

    • name 应该是主键。单独的列没有意义
    【解决方案5】:

    我通常在我的设置表中添加一个“类型”字段,以便我只检索所需的设置组,这对我来说是一种对类似设置进行分组并立即检索它们的方式。

    【讨论】:

    • 在什么情况下需要获取一组设置?主要是出于性能原因吗?
    • 一些设置被分组,例如 DirectoryPath,如果我正在寻找 DirectoryPath,我可以拉出 type = DirectoryPath 的所有设置,然后遍历它们。
    【解决方案6】:

    像这样创建一个键值表:

    settings:
    name NVARCHAR(255) PRIMARY KEY
    value NVARCHAR(255) NOT NULL
    

    【讨论】:

      【解决方案7】:

      首先,当您考虑应该将哪些信息存储在 web.config 文件中时,这一点也不无道理。当您更改程序集信息、连接字符串等内容时,您的应用程序需要停止并重新加载值以使用这些设置运行。

      如果您要存储应用程序范围的设置,那么您可以在数据库中创建一个设置表,甚至可以使用单独的文本文件来存储设置。

      如果您谈论的是存储每个用户的设置,您应该查看ASP.NET Profile Properties

      【讨论】:

      • “不合理”是指应用程序的不断“重新启动”是一种副作用,会出现我无法容忍的性能问题。 (并不是说重启背后的原因是不合理的......) - 感谢您指出 ASP.NET 配置文件属性。这不是我正在寻找的东西,但我认为它会帮助我解决我遇到的另一个问题...... :-)
      【解决方案8】:

      应用程序范围的设置当然应该存储在 web.config 文件的这一部分中,因为它可以防止硬编码值可能会随着时间而改变。无需使用您自己的代码读取它们,因为有一个内置方法:使用 System.Configuration.ConfigurationManager.AppSettings 数组来检索它们(您需要在项目中添加对 System.Configuration 程序集的引用)。您也可以通过 ASP.NET 网站管理工具编辑 AppSettings(项目菜单 -> ASP.NET 配置)。

      对于您设想在站点启动和运行期间更频繁地更改的值,使用 XML 文件、轻量级数据库(例如 SQLite 或 SQL Server Compact)甚至文本文件来进行这些设置是合理的。

      【讨论】:

        【解决方案9】:

        如果您需要保存设置,您可以随时将它们保存在自定义配置文件中。

        不久前我就这样做了,我有可用的代码here

        【讨论】:

          猜你喜欢
          • 2012-03-13
          • 1970-01-01
          • 2013-06-19
          • 2011-05-15
          • 1970-01-01
          • 2013-11-20
          • 2021-05-03
          • 2013-02-12
          • 1970-01-01
          相关资源
          最近更新 更多