【问题标题】:How to conditionally deploy an app.config based on build configuration?如何根据构建配置有条件地部署 app.config?
【发布时间】:2010-09-25 21:48:51
【问题描述】:

我有三个自定义构建配置 { Dev、Qs、Prd }。所以,我有三个应用程序配置 { Dev.config、Qs.config、Prd.config }。我知道如何编辑 .csproj 文件以根据当前构建配置输出正确的文件。

<Target Name="AfterBuild">
   <Delete Files="$(TargetDir)$(TargetFileName).config" />
   <Copy SourceFiles="$(ProjectDir)$(Configuration).config" DestinationFiles="$(TargetDir)$(TargetFileName).config" />
</Target>

我的问题是,我需要 六个 构建配置 { Dev, Qs, Prd } x { Debug, Release }。我需要支持每个环境的调试和发布设置(优化、pdb 等)。但是,应用配置值在调试/发布之间不会发生变化。

如何使构建脚本尽可能通用并仅使用三个应用配置?我不想硬编码太多的条件字符串。

【问题讨论】:

  • ”标签支持“条件”属性。我可以测试条件是否匹配“Dev_*”(如“Dev_Debug”或“Dev_Release”)以使用 Dev.config 文件吗?
  • 这是一个很好的hanselman.com/blog/… at scott Hanselmans,关于自动化多重配置。在 cmets 部分有一些替代解决方案。一些有趣的比如使用 delta of配置文件。其他一些就像为不同的环境提供不同的配置文件。
  • 仅供未来读者参考:我尝试了上面的代码并且它有效,但不适用于使用 ClickOnce 进行部署。它只是不包括在内。因此,我从blogs.msdn.com/b/vsto/archive/2010/03/09/… 寻求解决方案,这与史蒂夫的回答相似。

标签: .net deployment configuration msbuild


【解决方案1】:

使用构建服务器怎么样?
自从我在 .NET 中工作以来已经有很长时间了,但是您不能使用 Hudson(-like) 服务器来管理您的构建配置吗?不是更简单吗?
那么NAnt呢?它不符合您的需求吗?

【讨论】:

  • 詹姆斯,你是对的。在这一点上,我们已经超出了使用 csproj 文件的能力(和敏感性)。
【解决方案2】:

我们使用 csproj 文件中的选择元素解决了这个问题。我们设置了几种不同的配置,因此我们所做的就是将此块放入您的 proj 文件中,您可以使用 VS 的配置来帮助您。我确实想支持 Rob 的建议以移动传递的 app.config。一段时间以来,我一直在朝着这个方向前进。

  <Choose>
<When Condition=" '$(Configuration)' == 'Debug' ">
  <ItemGroup>
    <None Include="App.config" />
    <None Include="Release\App.config" />
  </ItemGroup>
</When>
<Otherwise>
  <ItemGroup>
    <None Include="Release\App.config">
      <Link>App.config</Link>
    </None>
  </ItemGroup>
</Otherwise>

【讨论】:

    【解决方案3】:

    我建议你的问题表明你已经过时了app.config——是时候转向更好的解决方案,并开始解决一些相关问题了。

    首先,您永远不应该将配置文件自动部署到生产环境中,并且您应该期望运营支持人员强烈拒绝任何这样做的尝试。当然,如果你是运营支持人员,那么你应该自己拒绝。相反,您的版本应该包含一些手动更新配置文件的说明,并带有一个示例进行说明。生产配置对于较小的措施来说太重要了,除非您根本不重视您的生产系统。

    对于测试和其他环境也是如此,但程度较轻,因此您实际上只需要为您自己的开发工作填充您的 app.config

    一种选择是将多个配置嵌入到单个app.config 中,这对于小型、相对不重要的应用程序或处于开发/发布的早期阶段是合理的。例如,创建一个名为 target-env 之类的配置设置,其中包含一个值,您可以在代码中使用该值来选择其他配置设置,例如将该值附加到其他配置设置的键上。

    我的偏好是完全跳过app.config,或者尽量少用它。在这种情况下,我更喜欢将足够的配置数据放入一个文件中,以允许我的应用程序/系统连接到它的数据库,然后我将剩余的配置详细信息放入一个特殊的数据库表中。这有很多优点,例如让数据库“了解”它所代表的环境(开发、测试、生产等)并将配置和其他数据保持在一起。然后,部署包可以在配置和环境差异方面保持沉默——代码只是访问其配置数据并采取相应的行动,因此相同的部署包适用于任何环境。

    但是,此方法的一个关键成功因素是您的应用程序代码必须“知道”它对配置的期望,并且它必须“知道”拒绝不正确/不完整的配置。这是您应该花时间的地方,而不是试图绕过app.config 的限制。

    这通常意味着创建您自己的类来访问配置数据,然后在整个应用程序中使用该类。这也带来了许多其他好处,例如强类型配置数据:而不是String,而是返回DateTime,或Url,或Integer,或Currency,或任何最好的适合配置数据和应用程序。

    【讨论】:

    • 有 10-15 个配置项:一个 URL,一个远程对象列表,一个文件列表。我按接口将配置源与格式分开。应用程序配置是可能和预期的来源。我更喜欢手动更新作为构建过程的一部分,但我必须为我的老板调查这条路径。
    • “首先,您永远不应该将配置文件自动部署到生产环境”尝试告诉微软!这些天他们坚持在 app/web.config 文件中的一些东西真的应该编译成 exe 文件。
    • 是的,我发现尝试告诉 Microsoft 任何事情都是徒劳的——我只是试图保护自己和我的客户免受影响。当您过渡到企业级部署时,这完美地说明了必要的更改。
    • 我同意上述大部分内容,但它暗示 app.config 仅适用于最简单的配置。您是否建议实施自定义配置解决方案?在这种情况下,依赖配置管理的专业级技术,如 WCF、Web 应用程序等呢?需求肯定存在。至于操作支持拒绝自动部署的配置文件 - 重点是您不应该部署可能在操作中更改的东西,但是许多开发人员在这方面设置了自己的策略。
    • @RobWilliams 你能解释一下为什么自动部署 app.config 文件这么糟糕吗?
    【解决方案4】:

    类似的东西

    <PropertyGroup Condition="'$(Configuration)'=='Dev_Debug' OR '$(Configuration)'=='Dev_Release'" >
        <CfgFileName>Dev</CfgFileName>
    </PropertyGroup>
    <!-- similar for Qs & Prd -->
    <Target ...>...$(CfgFileName).config...
    

    【讨论】:

    • 这在我添加第三个自定义构建配置之前有效。我收到一个错误:找不到 \.config。我认为这可能是我的环境的问题。我怀疑我是否想维护这么多 .csproj 配置。
    【解决方案5】:

    我想采用的最后一个解决方案是创建 6 个应用配置,每个自定义配置 1 个

    { Dev_Debug.config, Dev_Release.config, Qs_Debug.config, ... , Prd_Release.config }。

    尽管通过该设置,我可以维护通用构建脚本,而不使用条件字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-17
      • 1970-01-01
      • 1970-01-01
      • 2013-04-21
      • 2011-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多