Cómo seleccionar diferentes aplicaciones.config para varias configuraciones de compilación


Tengo un proyecto tipo dll que contiene pruebas de integración MSTest. En mi máquina las pruebas pasan, y quiero que lo mismo suceda en un servidor CI (uso TeamCity). Pero las pruebas fallan, porque necesito ajustar algunas configuraciones en la aplicación.config. Esta es la razón por la que estaba pensando en tener una segunda aplicación separada.archivo de configuración que contiene la configuración del servidor CI.

Así que me gustaría tener

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

Por lo tanto, si selecciono Release configuration en build config on CI, me gustaría usar app.Lanzar.archivo de configuración en lugar de aplicación.config

Problema
Esto no parece ser sencillo para simple .proyectos de tipo dll. Para proyectos web, puedo hacer transformaciones de configuración web. He encontrado un truco cómo hacer estas transformaciones para un proyecto de tipo dll, pero no soy un gran fan de hacks.

Pregunta
¿Qué es un enfoque estándar para ajustar la aplicación.archivos de configuración dependiendo de la configuración de compilación para proyectos. NET (como Debug, Release,...)?

Author: oleksii, 2011-11-10

10 answers

Use el plugin SlowCheetah. Para más opciones y detalles de cómo usar SlowCheetah sigue leyendo.

Como ya ha notado, no hay una forma predeterminada y fácil de usar diferentes archivos de configuración para un tipo de biblioteca (.dll) project. La razón es que el pensamiento actual es: "¡No necesitas"! Los desarrolladores de framework consideran que necesita configuración para el archivo ejecutable: ya sea una consola, escritorio, web, aplicación móvil u otra cosa. Si comienza a proporcionar configuración para una dll , puede terminar con algo que puedo llamar config hell . Es posible que ya no entienda (fácilmente) por qué esta y aquella variables tienen valores tan extraños que aparentemente vienen de la nada.

"Espera", - puedes decir, " pero necesito esto para mi integración / pruebas unitarias, y es una biblioteca!". Y eso es cierto y esto es lo que puedes hacer (elige solo uno, no mezcles):

1. SlowCheetah-transforma el archivo de configuración actual

Puede instalar SlowCheetah - un plug-in de Visual Studio que hace todos los XML de bajo nivel de empuje (o transformación) para usted. La forma en que funciona, brevemente:

  • Instale SlowCheetah y reinicie Visual Studio (Visual Studio > Herramientas > Extensiones y actualizaciones ... > En línea > Galería de Visual Studio > buscar "Guepardo lento")
  • Defina las configuraciones de su solución ( Debug y Release están por defecto), puede agregar más (haga clic derecho en la solución en Solución Explorador > Gestor de Configuración... > Configuración Activa de la Solución > Nuevo...
  • Agregue un archivo de configuración si es necesario
  • Haga clic derecho en archivo de configuración > Agregar Transformar
    • Esto creará archivos de transformación-uno por su configuración
    • Los archivos de transformación funcionan como inyectores / mutadores, encuentran el código XML necesario en el archivo de configuración original e inyectan nuevas líneas o mutan el valor necesario, lo que sea que le diga do

2. Juguetea .proj file-copy-renombra un archivo de configuración completamente nuevo

Originalmente tomado de aquí. Es una tarea personalizada de MSBuild que puede incrustar en Visual Studio .archivo proj . Copie y pegue el siguiente código en el archivo de proyecto

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

Ahora cree una carpeta en el proyecto llamada Config y agregue nuevos archivos allí: App.Depurar.config, App.Lanzar.config y así sucesivamente. Ahora, dependiendo de su configuración, Visual Studio seleccionará el archivo de configuración de una carpeta Config y lo copiará y cambiará el nombre en el directorio de salida. Así que si tuvieras PatternPA.Prueba.Integration project and a Debug config selected, in the output folder after the build you will find a PatternPA.Prueba.Integración.DLL.archivo config que fue copiado de Config\App.Debug.config y renombrado después.

Estas son algunas notas que puedes dejar en los archivos de configuración

<?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>

En Visual Studio puedes tener algo como esto

Estructura del proyecto

3. Usar archivos de scripting fuera de Visual Studio

Cada herramienta de compilación (como NAnt, MSBuild ) proporcionará capacidades para transformar el archivo de configuración dependiendo de la configuración. Esto es útil si construye su solución en una máquina de construcción, donde necesita tener más control sobre qué y cómo prepara el producto para el lanzamiento.

Por ejemplo, puede usar la tarea de dll de publicación web para transformar cualquier archivo de configuración

<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>
 141
Author: oleksii,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-17 05:20:01

Puede intentar el siguiente enfoque:

  1. Haga clic derecho en el proyecto en el Explorador de soluciones y seleccione Descargar proyecto.
  2. El proyecto se descargará. Haga clic con el botón derecho en el proyecto de nuevo y seleccione Edit .csproj .
  3. Ahora puede editar el archivo de proyecto dentro de Visual Studio.
  4. Localice el lugar en *.archivo csproj donde se incluye el archivo de configuración de la aplicación. Se verá como:
    <ItemGroup>
        <None Include="App.config"/>
    </ItemGroup>
  1. Sustitúyase esto líneas con lo siguiente:
    <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
        <None Include="App.Debug.config"/>
    </ItemGroup>

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

No he probado este enfoque para los archivos app.config, pero funcionó bien con otros elementos de proyectos de Visual Studio. Puede personalizar el proceso de compilación de casi cualquier manera que desee. De todos modos, hazme saber el resultado.

 23
Author: VHaravy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-10 16:41:33

Debe considerar ConfigGen. Fue desarrollado para este propósito. Produce un archivo de configuración para cada máquina de implementación, basado en un archivo de plantilla y un archivo de configuración. Sé que esto no responde a su pregunta específicamente, pero bien podría responder a su problema.

Entonces, en lugar de Depurar, Liberar, etc., es posible que tenga Pruebas, UAT, Producción, etc. También puede tener diferentes configuraciones para cada máquina desarrolladora, de modo que pueda generar una configuración específica para su máquina de desarrollo y cambiarlo sin afectar el despliegue de nadie más.

Un ejemplo de uso podría ser...

<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>

Si coloca esto en su .archivo csproj, y tiene los siguientes archivos...

$(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>

... entonces este será el resultado...

Desde el primer comando, se genera un archivo de configuración para cada entorno especificado en el archivo xls, colocado en el directorio de salida Config (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>

Desde el segundo comando, la aplicación local.configuración utilizada en su desarrollador la máquina será reemplazada por la configuración generada especificada por el conmutador local (-l) y el conmutador filename (-n).

 11
Author: Daniel Dyson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-10 16:53:55

Usando el mismo enfoque que Romeo, lo adapté a Visual Studio 2010:

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

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

Aquí es necesario mantener tanto Aplicación.config archivos en diferentes directorios (appDebug y appRelease). Lo probé y funciona bien!

 9
Author: tem peru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-03 10:33:52

Estoy usando XmlPreprocess tool para la manipulación de archivos de configuración. Está utilizando un archivo de asignación para múltiples entornos (o múltiples destinos de compilación en su caso). Puede editar el archivo de asignación por Excel. Es muy fácil de usar.

 3
Author: Ludwo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-11 06:10:56

SlowCheetah y FastKoala de la galería VisualStudio parecen ser muy buenas herramientas que ayudan con este problema.

Sin embargo, si desea evitar los complementos o utilizar los principios que implementan más ampliamente a lo largo de sus procesos de compilación/integración, agregar esto a sus archivos msbuild *proj es una corrección abreviada.

Nota: esto es más o menos una reelaboración del No.2 de la respuesta de @oleksii.

Esto funciona para .exe y .proyectos dll:

  <Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
    <TransformXml Source="App_Config\app.Base.config" Transform="App_Config\app.$(Configuration).config" Destination="app.config" />
  </Target>

Esto funciona para proyectos web:

  <Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
    <TransformXml Source="App_Config\Web.Base.config" Transform="App_Config\Web.$(Configuration).config" Destination="Web.config" />
  </Target>

Tenga en cuenta que este paso ocurre incluso antes de que comience la compilación propiamente dicha. La transformación del archivo de configuración ocurre en la carpeta del proyecto. Para que la web transformada.la configuración está disponible cuando se está depurando (un inconveniente de SlowCheetah).

Recuerde que si crea la carpeta App_Config (o como elija llamarlo), los varios archivos de configuración intermedios deben tener una Acción de compilación = Ninguno, y Copiar al Directorio de salida = No copia.

Esto combina ambas opciones en un bloque. El apropiado se ejecuta en base a las condiciones. Sin embargo, la tarea TransformXml se define primero:

<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>

 3
Author: Eniola,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-11 08:06:44

Ver si el XDT (web.config) transform engine puede ayudarle. Actualmente solo es compatible de forma nativa para proyectos web, pero técnicamente no hay nada que te impida usarlo en otros tipos de aplicaciones. Hay muchas guías sobre cómo usar XDT editando manualmente los archivos del proyecto, pero encontré un plugin que funciona muy bien: https://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859

El plugin solo está ayudando a configurar la configuración, no es necesario para construir y la solución se puede construir en otras máquinas o en un servidor de compilación sin necesidad de usar el plugin o cualquier otra herramienta.

 1
Author: TGasdf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-10 12:13:26

He resuelto este tema con la solución que he encontrado aquí: http://www.blackwasp.co.uk/SwitchConfig.aspx

En resumen, lo que dicen que hay: "añadiendo un evento post-build.[...] Tenemos que añadir lo siguiente:

if "Debug"=="$(ConfigurationName)" goto :nocopy
del "$(TargetPath).config"
copy "$(ProjectDir)\Release.config" "$(TargetPath).config"
:nocopy
 0
Author: Janbro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-23 13:12:23

Después de algunas investigaciones sobre la gestión de configuraciones para el desarrollo y compilaciones, etc., decidí rodar la mía, la he puesto a disposición en bitbucket en: https://bitbucket.org/brightertools/contemplate/wiki/Home

Estos archivos de configuración múltiples para múltiples entornos, es una herramienta de reemplazo de entrada de configuración básica que funcionará con cualquier formato de archivo basado en texto.

Espero que esto ayude.

 0
Author: Mark Redman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-23 07:25:48

He oído cosas buenas acerca de SlowCheetah, pero no fue capaz de conseguir que funcione. Hice lo siguiente: agregar etiqueta am a cada uno para una configuración específica.

Ex:

<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>
 0
Author: Mike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-02 19:33:18