.net 如何为多个生成配置选择不同的app.config

.net 如何为多个生成配置选择不同的app.config,.net,visual-studio,configuration,continuous-integration,release-management,.net,Visual Studio,Configuration,Continuous Integration,Release Management,我有一个dll类型的项目,其中包含MSTest集成测试。在我的机器上,测试通过了,我希望在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 ind

我有一个dll类型的项目,其中包含MSTest集成测试。在我的机器上,测试通过了,我希望在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) /Sln /项目 app.config(我认为这是VS需要的) app.Release.config(这是一个独立的配置文件) 因此,如果我在CI的build config中选择Release configuration,我希望使用app.Release.config文件而不是app.config

问题
对于简单的.dll类型的项目来说,这似乎并不简单。对于web项目,我可以进行web配置转换。我发现了一个如何为dll类型的项目进行这些转换的技巧,但我不太喜欢这种技巧

问题
根据.NET项目的构建配置(如调试、发布、……),如何调整App.CONFIG文件的标准方法是什么?

< P>。它就是为此而开发的。它基于模板文件和设置文件为每个部署计算机生成一个配置文件。我知道这并没有具体回答你的问题,但它很可能回答你的问题

因此,您可能需要测试、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>

如果您将其放在.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>
$(ProjectDir)App.Config.Settings.xls
MachineName配置文件路径SQLServer
默认App.config DEVSQL005
Test App.config TESTSQL005
UAT App.config UATSQL005
生产App.config PRODSQL005
YourLocalMachine App.config./SQLEXPRESS
$(ProjectDir)App.config.template.xml
。。。那么这就是结果

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

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

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

您可以尝试以下方法:

  • 右键单击解决方案资源管理器中的项目,然后选择卸载项目
  • 项目将被卸载。再次右键单击项目并选择编辑.csproj
  • 现在,您可以在VisualStudio中编辑项目文件
  • 在*.csproj文件中找到包含应用程序配置文件的位置。它看起来像:
  • 将此行替换为以下内容:
  • 我还没有尝试过对
    app.config
    文件使用这种方法,但它在VisualStudio项目的其他项目中运行良好。您几乎可以用任何喜欢的方式自定义构建过程。无论如何,请告诉我结果。

    我正在使用配置文件操作。它将一个映射文件用于多个环境(或者在您的情况下使用多个构建目标)。您可以通过Excel编辑映射文件。它很容易使用。

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

    正如您已经注意到的,对于库类型(.dll)项目,没有默认且简单的方法来使用不同的配置文件。原因是目前的想法是:“你不需要”!框架开发人员认为您需要对可执行文件进行配置:可以是控制台、桌面、web、移动应用程序或其他。如果您开始为dll提供配置,您可能会得到我称之为配置地狱的东西。您可能不再(轻松地)理解为什么这个和那个变量有如此奇怪的值,似乎不知从何而来

    “等等”,你可能会说,“但是我需要这个来进行集成/单元测试,它是一个库!”。这是真的,这就是你能做的(只选一个,不要混合):

    1.SlowCheetah-转换当前配置文件 您可以安装一个VisualStudio插件,它可以为您执行所有低级XML戳(或转换)。它的工作方式,简而言之:

    • 安装SlowCheetah并重新启动Visual Studio(Visual Studio>工具>扩展和更新…>联机>Visual Studio库>搜索“Slow Cheetah”)
    • 定义您的解决方案配置(默认情况下存在调试和发布),您可以添加更多(右键单击解决方案资源管理器>配置管理器…>活动解决方案配置>新建中的解决方案…)
    • 如果需要,添加一个配置文件
    • 右键单击配置文件>添加转换
      • 这将创建转换文件-每个配置一个
      • 转换文件作为注入器/变异器工作,它们在原始配置文件中找到所需的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>
    
    在VisualStudio中,您可以有这样的内容

    3.在Visual Studio外部使用脚本文件 每个构建工具(如,)都将提供根据配置转换配置文件的功能。如果您在需要更多配置的构建机器上构建解决方案,这将非常有用 <ItemGroup> <None Include="App.config"/> </ItemGroup> <ItemGroup Condition=" '$(Configuration)' == 'Debug' "> <None Include="App.Debug.config"/> </ItemGroup> <ItemGroup Condition=" '$(Configuration)' == 'Release' "> <None Include="App.Release.config"/> </ItemGroup>
    <Target Name="AfterBuild">
        <Delete Files="$(TargetDir)$(TargetFileName).config" />
        <Copy SourceFiles="$(ProjectDir)\Config\App.$(Configuration).config"
              DestinationFiles="$(TargetDir)$(TargetFileName).config" />
    </Target>
    
    <?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>
    
    <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>
    
     <None Condition=" '$(Configuration)' == 'Debug' " Include="appDebug\App.config" />
    
     <None Condition=" '$(Configuration)' == 'Release' " Include="appRelease\App.config" />
    
      <Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
        <TransformXml Source="App_Config\app.Base.config" Transform="App_Config\app.$(Configuration).config" Destination="app.config" />
      </Target>
    
      <Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
        <TransformXml Source="App_Config\Web.Base.config" Transform="App_Config\Web.$(Configuration).config" Destination="Web.config" />
      </Target>
    
    <Project>
    <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
    <Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
        <TransformXml Condition="Exists('App_Config\app.Base.config')" Source="App_Config\app.Base.config" Transform="App_Config\app.$(Configuration).config" Destination="app.config" />
        <TransformXml Condition="Exists('App_Config\Web.Base.config')" Source="App_Config\Web.Base.config" Transform="App_Config\Web.$(Configuration).config" Destination="Web.config" />
    </Target>
    
    if "Debug"=="$(ConfigurationName)" goto :nocopy
    del "$(TargetPath).config"
    copy "$(ProjectDir)\Release.config" "$(TargetPath).config"
    :nocopy
    
    <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>