如何为多个构建配置选择不同的app.config

ole*_*sii 114 .net configuration continuous-integration release-management visual-studio

我有一个包含MSTest集成测试的dll类型项目.在我的机器上测试通过,我希望在CI服务器上发生同样的事情(我使用TeamCity).但是测试失败了,因为我需要在app.config中调整一些设置.这就是为什么我想要一个单独的第二个app.config文件来保存CI服务器的设置.

所以我想拥有

/Sln
 /Proj
  app.config (I think this is required by VS)
  app.Release.config (This is a standalone independent config file)

因此,如果我在CI上的构建配置中选择Release配置,我想使用app.Release.config文件而不是app.config

问题
对于简单的.dll类型项目,这似乎并不简单.对于Web项目,我可以进行Web配置转换.我找到了一个黑客如何为dll类型的项目进行这些转换,但我不是黑客的忠实粉丝.

问题
根据.NET项目的构建配置(例如Debug,Release,...)调整app.config文件的标准方法是什么?

ole*_*sii 151

使用SlowCheetah插件.有关如何使用SlowCheetah继续阅读的更多选项和详细信息.

正如您已经注意到的那样,没有默认的简单方法可以为库类型(.dll)项目使用不同的配置文件.原因是目前的想法是:"你不需要"!框架开发人员认为您需要配置可执行文件:无论是控制台,桌面,Web,移动应用程序还是其他内容.如果你开始为一个dll提供配置,你可能会得到一些我称之为配置地狱的东西.您可能不再(轻易地)理解为什么这个和那些变量看起来似乎无处可见.

"等等", - 你可能会说,"但我需要这个用于我的集成/单元测试,它是一个库!".这是真的,这是你可以做的(只选一个,不要混合):

1. SlowCheetah - 转换当前配置文件

您可以安装SlowCheetah - 一个Visual Studio插件,为您执行所有低级XML戳(或转换).它的工作方式,简要说明:

  • 安装SlowCheetah并重新启动Visual Studio(Visual Studio>工具>扩展和更新...>在线> Visual Studio库>搜索"慢速猎豹")
  • 定义您的解决方案配置(默认情况下是DebugRelease),您可以添加更多(右键单击解决方案资源管理器中的解决方案 > Configuration Manager ... > Active Solution Configuration > New ...
  • 如果需要,添加配置文件
  • 右键单击配置文件> 添加转换
    • 这将创建Transformation文件 - 每个配置一个
    • 转换文件作为注入器/更改器工作,它们在原始配置文件中找到所需的XML代码并注入新行或改变所需的值,无论你告诉它做什么

2.摆弄.proj文件 - 复制 - 重命名一个全新的配置文件

最初取自这里.这是一个自定义的MSBuild任务,您可以将其嵌入到Visual Studio .proj文件中.将以下代码复制并粘贴到项目文件中

<Target Name="AfterBuild">
    <Delete Files="$(TargetDir)$(TargetFileName).config" />
    <Copy SourceFiles="$(ProjectDir)\Config\App.$(Configuration).config"
          DestinationFiles="$(TargetDir)$(TargetFileName).config" />
</Target>
Run Code Online (Sandbox Code Playgroud)

现在在项目中创建一个名为的文件夹,Config并在那里添加新文件:App.Debug.config,App.Release.config等.现在,根据您的配置,Visual Studio将从文件Config夹中选择配置文件,并将其重命名为输出目录.因此,如果您选择了PatternPA.Test.Integration项目并选择了Debug配置,则在构建之后的输出文件夹中,您将找到一个PatternPA.Test.Integration.dll.config文件,该文件之后已复制并重Config\App.Debug.config命名.

这些是您可以在配置文件中留下的一些注释

<?xml version="1.0" encoding="utf-8"?>
<configuration>

    <!-- This file is copied and renamed by the 'AfterBuild' MSBuild task -->

    <!-- Depending on the configuration the content of projectName.dll.config 
        is fully substituted by the correspondent to build configuration file 
        from the 'Config' directory. -->

</configuration>
Run Code Online (Sandbox Code Playgroud)

在Visual Studio中,您可以拥有这样的东西

项目结构

3.在Visual Studio外部使用脚本文件

每个构建工具(如NAnt,MSBuild)将提供根据配置转换配置文件的功能.如果您在构建计算机上构建解决方案,这将非常有用,您需要更好地控制准备产品以供发布的内容和方式.

例如,您可以使用Web发布dll的任务来转换任何配置文件

<UsingTask AssemblyFile="..\tools\build\Microsoft.Web.Publishing.Tasks.dll"
    TaskName="TransformXml"/>

<PropertyGroup>
    <!-- Path to input config file -->  
    <TransformInputFile>path to app.config</TransformInputFile>
    <!-- Path to the transformation file -->    
    <TransformFile>path to app.$(Configuration).config</TransformFile>
    <!-- Path to outptu web config file --> 
    <TransformOutputFile>path to output project.dll.config</TransformOutputFile>
</PropertyGroup>

<Target Name="transform">
    <TransformXml Source="$(TransformInputFile)"
                  Transform="$(TransformFile)"
                  Destination="$(TransformOutputFile)" />
</Target>
Run Code Online (Sandbox Code Playgroud)

  • @MassoodKhaari您需要确保为发布目标调用此任务.当您发布项目时,会调用一个单独的构建目标,默认情况下可能不会调用`AfterBuild`目标.在典型编译期间,默认情况下会调用`AfterBuild`目标.应该快速修复发布案例 (3认同)
  • 我正在使用第二种方法,但需要向 AfterBuild 目标添加一个条件,以确保文件在删除之前确实存在。我有一个调试构建配置,它基本上只使用默认的 App.config 文件,但我没有 App.Debug.config,这意味着构建步骤将失败。我刚刚添加了`Condition="Exists('$(ProjectDir)App.$(Configuration).config')"`。 (2认同)

VHa*_*avy 22

您可以尝试以下方法:

  1. 在Solution Explorer中右键单击项目,然后选择Unload Project.
  2. 该项目将被卸载.再次右键单击该项目,然后选择Edit <YourProjectName> .csproj.
  3. 现在,您可以在Visual Studio中编辑项目文件.
  4. 在*.csproj文件中找到包含应用程序配置文件的位置.它看起来像:
    <ItemGroup>
        <None Include="App.config"/>
    </ItemGroup>
  1. 将此行替换为以下内容:
    <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
        <None Include="App.Debug.config"/>
    </ItemGroup>

    <ItemGroup Condition=" '$(Configuration)' == 'Release' ">
        <None Include="App.Release.config"/>
    </ItemGroup>

我没有尝试过这种方法来处理app.config文件,但它可以与其他Visual Studio项目一起使用.您可以以您喜欢的任何方式自定义构建过程.无论如何,让我知道结果.

  • 这里解释了如何做到这一点:[启用app.debug.config app.release.config](http://mitasoft.wordpress.com/2011/09/28/multipleappconfig/) (2认同)

Dan*_*son 12

你应该考虑ConfigGen.它是为此目的而开发的.它根据模板文件和设置文件为每个部署机器生成配置文件.我知道这并没有具体回答你的问题,但它可能很好地回答你的问题.

因此,您可能拥有测试,UAT,生产等,而不是调试,发布等.您还可以为每台开发人员计算机设置不同的设置,以便您可以生成特定于您的开发计算机的配置并更改它,而不会影响任何其他人的部署.

使用的一个例子可能是......

<Target Name="BeforeBuild">
    <Exec Command="C:\Tools\cfg -s $(ProjectDir)App.Config.Settings.xls -t       
        $(ProjectDir)App.config.template.xml -o $(SolutionDir)ConfigGen" />

    <Exec Command="C:\Tools\cfg -s $(ProjectDir)App.Config.Settings.xls -t
        $(ProjectDir)App.config.template.xml -l -n $(ProjectDir)App.config" />
</Target>
Run Code Online (Sandbox Code Playgroud)

如果您将其放在.csproj文件中,并且您有以下文件...

$(ProjectDir)App.Config.Settings.xls

MachineName        ConfigFilePath   SQLServer        

default             App.config      DEVSQL005
Test                App.config      TESTSQL005
UAT                 App.config      UATSQL005
Production          App.config      PRODSQL005
YourLocalMachine    App.config      ./SQLEXPRESS


$(ProjectDir)App.config.template.xml 

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
   <configuration>
   <appSettings>
       <add key="ConnectionString" value="Data Source=[%SQLServer%]; 
           Database=DatabaseName; Trusted_Connection=True"/>
   </appSettings>
</configuration>
Run Code Online (Sandbox Code Playgroud)

......那么这将是结果......

从第一个命令,为xls文件中指定的每个环境生成的配置文件,放在输出目录$(SolutionDir)ConfigGen中

.../solutiondir/ConfigGen/Production/App.config

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
   <configuration>
   <appSettings>
       <add key="ConnectionString" value="Data Source=PRODSQL005; 
           Database=DatabaseName; Trusted_Connection=True"/>
   </appSettings>
</configuration>
Run Code Online (Sandbox Code Playgroud)

从第二个命令开始,dev计算机上使用的本地App.config将替换为本地(-l)开关和文件名(-n)开关指定的生成的配置.

  • Tnx的答案,这看起来不错.但是有一些缺点,它只显示75次下载(因此它不成熟),它只适用于.xls或.xlsx.我真的不想依赖于另一种自定义文档格式来进行简单的操作.我一直在寻找更标准的方法...... (2认同)
  • 虽然它在CodePlex上有194次下载,但是xls是一个电子表格,几乎不是自定义格式,我知道有三家大型投资银行已经批准使用它,所以如果它对他们来说已经足够好了......还有一个当前请求的功能是使用xml进行设置.它已接近准备好了,但无论如何我更喜欢电子表格方法.在表格视图中查看每个环境的每个设置要容易得多 (2认同)

小智 10

使用与Romeo相同的方法,我将其改编为Visual Studio 2010:

 <None Condition=" '$(Configuration)' == 'Debug' " Include="appDebug\App.config" />

 <None Condition=" '$(Configuration)' == 'Release' " Include="appRelease\App.config" />
Run Code Online (Sandbox Code Playgroud)

在这里,您需要将两个App.config文件保存在不同的目录中(appDebug和appRelease).我测试了它,它工作正常!


Mik*_*ike 9

我听说过 SlowCheetah 的好消息,但无法让它发挥作用。我执行了以下操作:为每个特定配置添加 am 标签。

前任:

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'UAT|AnyCPU'">
    <OutputPath>bin\UAT\</OutputPath>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <AppConfig>App.UAT.config</AppConfig>
  </PropertyGroup>
Run Code Online (Sandbox Code Playgroud)