如何为 .NET 中的不同环境使用不同的 .settings 文件?

Posted

技术标签:

【中文标题】如何为 .NET 中的不同环境使用不同的 .settings 文件?【英文标题】:How to use different .settings files for different environments in .NET? 【发布时间】:2011-01-15 20:58:02 【问题描述】:

.NET 允许您使用 .settings 文件来管理应用程序设置。我想以我可以执行以下操作的方式分别存储生产、开发和测试设置:

EnvironmentSettings environmentSettings;

// get the current environment (Production, Development or Test)
ApplicationEnvironment Environment = (ApplicationEnvironment)
    Enum.Parse(typeof(ApplicationEnvironment), Settings.Default.ApplicationEnvironment);

switch (Environment)

    case ApplicationEnvironment.Production:
        environmentSettings = Settings.Production;
        break;
    ...


string reportOutputLocation = environmentSettings.ReportOutputLocation;

基本上,我想要两个单独的 Settings 类:存储所选环境和非环境特定属性的通用 Settings 类,以及名为 EnvironmentSettings 的第二个类的 3 个静态实例。使用的实例应取决于通用 Settings 类中指定的环境。

除了在静态构造函数或其他东西中手动设置所有这些设置的值之外,还有什么方法可以做到这一点?如果我必须这样做,我宁愿只拥有一个具有“DevOutputLocation”、“LiveOutputLocation”等属性的大型设置类。

我的项目中可以有多个 .settings 文件,但这只会创建不相互派生的单独类。所以我可以制作 DevelopmentSettings.settings、ProductionSettings.settings 和 TestSettings.settings 文件并赋予它们相同的属性,但是我需要到处使用一堆 switch 语句来确定要使用哪个类,因为它们不是从公共类派生的.

【问题讨论】:

你可以通过为每个环境使用不同的用户来做到这一点,但不知何故,我认为这会导致比它解决的问题更多。 【参考方案1】:

我目前正在做类似于 pdavis 提到的解决方案的事情。但是为了简化多个配置文件,我使用 T4 模板来创建特定于环境的配置文件。这样就有一个 web.tt 文件来处理默认 web.config 文件的生成。每个环境都有自己的模板文件(qa.tt、production.tt 等),它继承自 web.tt 并包含任何特定于环境的覆盖。对网络配置的任何更改 - 新的应用设置、配置设置等都会通过重新生成模板自动传播到所有区域特定的配置文件,您不必担心使用差异工具保持文件同步。

【讨论】:

【参考方案2】:

进行检查以确定您正在运行的环境会涉及一些开销。如果您正在谈论的是 Web 环境,那么这可能意味着对性能的重大影响。我建议创建三个单独的配置文件并设置一个持续集成和部署系统,该系统根据环境处理命名和推出适当的设置文件。在您的情况下,您将拥有三个文件,Production.config、Development.config 和 Test.config。然后,集成服务器将根据环境为 web.config 或 app.config 创建此文件的副本。

只要进行配置更改时维护三个单独的文件所涉及的任何额外维护,我们都会将文件保持自动格式化并使用 WinMerge 之类的工具来轻松查看差异并保持它们正确同步。这些类型的文件通常不需要进行太多更改,并且在更改时通常是少量添加。

【讨论】:

【参考方案3】:

只是一些关于基于 .NET 环境的配置文件的额外信息,而无需专门使用您的上述实现:

Enterprise Library 从 V3.0 开始就有这个特性: Summary

Visual Studio 2010 也将具有此功能。它叫Config Transformation

【讨论】:

【参考方案4】:

我正在对 .config 文件使用这种方法,我相信它也会对您有所帮助。 看看Scott Hanselman's blog post 和this question。意识形态很简单,但效果很好。您只需要:

    为不同的配置创建多个文件 按约定命名,例如我的.dev.settings,我的.live.settings 创建构建后事件(参见链接) 享受 =)

带有设置的类的实例化代码将始终在默认设置中查找(在每次构建后将替换为所需的设置),因此这种方法需要最少的工作。

【讨论】:

这真的是唯一的方法吗?我想如果它得到 Scott H 的认可,那么它似乎是一个非常混乱的黑客攻击。您可能会认为您可以为每个构建配置指定要使用的 .settings 或 .config 文件。 我刚刚回顾了我之前提出的问题,并注意到我从未将其标记为已回答,所以你去吧。再次感谢。 另一种可能性是使用像SlowCheetah这样的XML转换工具【参考方案5】:

一个想法是,在一系列静态值之间切换听起来像是一种相当令人担忧的做事方式。 我建议查找单例模式。此模式为您提供了一个在对该类的所有引用之间共享的单个类实例,但是当它第一次加载时,您可以执行正常的初始化位来检查您的环境并相应地设置值。

同样,与其使用开关来作用于不同的类,您难道不会考虑设计一个接口,并让每个类都实现该接口吗?

【讨论】:

【参考方案6】:

只是一个想法,但它可能会奏效......

您需要 N+2 个设置文件(N 不同的构建; 2个主人)与 包含相同的键。

清除“自定义工具”属性 除了其中一位大师之外的所有人(所以 只有一个master生成)。

修改每个版本的预构建脚本,将适当的设置文件内容复制到构建主文件中。

修改构建后脚本以将辅助主文件内容复制回原始主文件。

注意:如果您可以在构建前和构建后脚本中使用源代码控制提供程序,则不需要辅助主控器 - 您只需在预构建中签出并在构建后。但是,这可能会在持续集成环境中导致问题,因为锁定的文件会导致构建失败。

我也从来没有这样做过;虽然有时我希望在 VS 中有一种更先进的方式来做这样的事情。

【讨论】:

以上是关于如何为 .NET 中的不同环境使用不同的 .settings 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Azure Pipelines 中的每个阶段使用不同的服务连接?

如何为 asp.net vnext 使用不同的 .net 语言 (F#)

如何为不同的 QWebEnginePage 实例设置不同的代理?

如何为不同环境的 SwiftUI App 生命周期应用程序运行 UI 测试?

如何为指向两个不同域的一个 Laravel 应用程序设置不同的语言环境?

如何为不同的 SQL Server 文件夹运行相同的 angularjs 应用程序(.NET MVC 5)?