Comment sélectionner une application différente.config pour plusieurs configurations de construction

J'ai un projet de type dll {[3] } qui contient des tests D'intégration MSTest. Sur ma machine, les tests passent, et je veux que la même chose se produise sur un serveur CI (j'utilise TeamCity). Mais les tests échouent, car je dois modifier certains paramètres dans l'application.config. C'est pourquoi je pensais avoir une deuxième application.fichier de configuration qui contiendra les paramètres du serveur CI.

, Donc je voudrais avoir

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

Ainsi, si je sélectionne Release configuration dans build config sur CI, je voudrais utiliser App.Publier.fichier de configuration au lieu d'application.config

Problème
Cela ne semble pas être simple pour simple .projets de type dll. Pour les projets web, Je peux faire des transformations de configuration web. J'ai trouvé un hack comment faire ces transformations pour un projet de type dll, mais je ne suis pas un grand fan de hacks.

Question
Qu'est-ce qu'une approche standard pour modifier l'application.fichiers de configuration en fonction de la configuration de construction pour les projets. net (tels que Debug, Release, ...)?

101
demandé sur oleksii 2011-11-10 20:17:28

10 réponses

Utilisez le pluginSlowCheetah . Pour plus d'options et de détails sur la façon d'utiliser SlowCheetah continuer à lire.

Comme vous l'avez déjà remarqué, il n'y a pas de moyen par défaut et facile d'utiliser différents fichiers de configuration pour un type de bibliothèque (.dll) projet. La raison en est que la pensée actuelle est: "Vous n'avez pas besoin"! Les développeurs de Framework estiment que vous avez besoin de configuration pour le fichier exécutable: que ce soit une console, un bureau, un web, une application mobile ou autre chose. Si vous commencez à fournir la configuration pour un dll, vous pouvez vous retrouver avec quelque chose que je peux appeler un config de l'enfer. Vous ne pouvez plus comprendre (facilement) pourquoi ceci et que les variables ont des valeurs aussi étranges venant apparemment de nulle part.

"Hold on", - vous pouvez dire, "mais j'en ai besoin pour mon intégration/tests unitaires, c'est une bibliothèque!". Et c'est vrai et c'est ce que vous pouvez faire (choisissez un seul, ne mélangez pas):

1. SlowCheetah-transforme le fichier de configuration actuel

Vous pouvez installer SlowCheetah - un plug-in Visual Studio qui fait tous les bas niveau XML piquer (ou transformation) pour vous. La façon dont cela fonctionne, brièvement:

  • installez SlowCheetah et redémarrez Visual Studio (Visual Studio > Outils > Extensions et mises à jour ... > En ligne > galerie Visual Studio > rechercher "Cheetah lent")
  • Définissez vos configurations de solution ( Debug et Release sont là par défaut), vous pouvez en ajouter d'autres (faites un clic droit sur la solution dans Solution Explorateur > Gestionnaire De Configuration... > Configuration De La Solution Active > De Nouvelles...
  • Ajouter un fichier de configuration si nécessaire
  • cliquez-Droit sur le fichier de config > Ajouter Transformer
    • cela créera des fichiers de Transformation-un par votre configuration
    • les fichiers de transformation fonctionnent comme des injecteurs / mutateurs, ils trouvent le code XML nécessaire dans le fichier de configuration d'origine et injectent de nouvelles lignes ou mutent la valeur nécessaire, tout ce que vous lui dites do

2. Tripoter .proj file-copy-renomme un tout nouveau fichier de configuration

Tiré à l'origine de ici. C'est une tâche MSBuild personnalisée que vous pouvez intégrer dans Visual Studio .fichier proj . Copiez et collez le code suivant dans le fichier de projet

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

Créez maintenant un dossier dans le projet appelé Config et ajoutez de nouveaux fichiers: App.Débogage.config, App.Publier.config et ainsi de suite. Maintenant, en fonction de votre configuration, Visual Studio choisira le fichier de configuration à partir d'un dossier Config, et le copy-renommera dans le répertoire de sortie. Donc, si vous aviez PatternPA.Test.Intégration projet etDebug Config sélectionné, dans le dossier de sortie après la construction, vous trouverez un PatternPA.Test.Intégration.DLL.config fichier qui a été copié à partir de Config\App.Debug.config et renommé par la suite.

Voici quelques notes que vous pouvez laisser dans les fichiers de configuration

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

Dans Visual Studio, vous pouvez avoir quelque chose comme ce

La structure du projet

3. Utiliser des fichiers de script en dehors de Visual Studio

Chaque outil de construction (comme NAnt, MSBuild) fournira des possibilités pour transformer fichier de configuration en fonction de la configuration. Ceci est utile si vous construisez votre solution sur une machine de construction, où vous devez avoir plus de contrôle sur quoi et comment vous préparez le produit pour la libération.

Par exemple, vous pouvez utiliser la tâche dll de publication web pour transformer n'importe quel fichier de 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>
141
répondu oleksii 2017-05-17 05:20:01

Vous pouvez essayer l'approche suivante:

  1. cliquez-Droit sur le projet dans l'Explorateur de solutions et sélectionnez Décharger le Projet.
  2. , Le projet sera déchargé. Cliquez à nouveau avec le bouton droit sur le projet et sélectionnez Edit .csproj .
  3. Vous pouvez maintenant modifier le fichier de projet dans Visual Studio.
  4. Localisez l'endroit dans *.fichier csproj où votre fichier de configuration de l'application est inclus. Il ressemblera à:
    <ItemGroup>
        <None Include="App.config"/>
    </ItemGroup>
  1. remplacez ceci lignes avec ce qui suit:
    <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
        <None Include="App.Debug.config"/>
    </ItemGroup>

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

Je n'ai pas essayé cette approche pour les fichiers app.config, mais cela a bien fonctionné avec d'autres éléments de projets Visual Studio. Vous pouvez personnaliser le processus de construction de presque n'importe quelle façon que vous le souhaitez. De toute façon, laissez-moi savoir la suite.

23
répondu VHaravy 2011-11-10 16:41:33

Vous devriez considérer ConfigGen . Il a été développé à cet effet. Il produit un fichier de configuration pour chaque machine de déploiement, basé sur un fichier de modèle et un fichier de paramètres. Je sais que cela ne répond pas spécifiquement à votre question, mais cela pourrait bien répondre à votre problème.

Donc, plutôt que de déboguer, de publier, etc., vous pourriez avoir Test, UAT, Production, etc. Vous pouvez également avoir des paramètres différents pour chaque machine de développement, de sorte que vous pouvez générer une configuration spécifique à votre machine de développement et changez-le sans affecter le déploiement de quelqu'un d'autre.

Un exemple d'utilisation pourrait être...

<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 vous placez cela dans votre .fichier csproj, et vous avez les fichiers suivants...

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

... ensuite, ce sera le résultat...

A partir de la première commande, un fichier de configuration généré pour chaque environnement spécifié dans le fichier xls, placé dans le répertoire de sortie $ (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>

À partir de la deuxième commande, l'application locale.config utilisé sur votre dev la machine sera remplacée par la configuration générée spécifiée par le commutateur local (-l) et le commutateur filename (-n).

11
répondu Daniel Dyson 2011-11-10 16:53:55

En utilisant la même approche que Romeo, Je l'ai adapté à Visual Studio 2010:

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

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

Ici, vous devez garder les deux App.fichiers de configuration dans différents répertoires (appDebug et applelease). Je l'ai testé et cela fonctionne très bien!

9
répondu tem peru 2018-05-03 10:33:52

J'utilise XmlPreprocess tool pour la manipulation des fichiers de configuration. Il utilise un fichier de mappage pour plusieurs environnements (ou plusieurs cibles de construction dans votre cas). Vous pouvez modifier le fichier de mappage par Excel. Il est très facile à utiliser.

3
répondu Ludwo 2011-11-11 06:10:56

SlowCheetah et FastKoala de la galerie VisualStudio semblent être de très bons outils pour résoudre ce problème.

Cependant, si vous voulez éviter les addins ou utiliser les principes qu'ils implémentent plus largement tout au long de vos processus de construction/intégration, l'ajout de ceci à vos fichiers MSBuild *proj est un raccourci.

Note: c'est plus ou moins une reprise du numéro 2 de la réponse de @oleksii.

Cela fonctionne pour .exe et .projets dll:

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

Cela fonctionne pour les projets web:

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

Notez que cette étape se produit avant même le début de la construction proprement dite. La transformation du fichier de configuration se fait dans le dossier du projet. Alors que le web transformé.config est disponible lorsque vous déboguez (un inconvénient de SlowCheetah).

Rappelez-vous que si vous créez le dossier App_Config (ou tout ce que vous choisissez de l'appeler), les différents fichiers de configuration intermédiaires doivent avoir une action de construction = None, et copier dans le répertoire de sortie = ne pas copie.

Cela combine les deux options en un seul bloc. Le approprié est exécuté en fonction des conditions. La tâche TransformXml est définie en premier:

<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
répondu Eniola 2018-05-11 08:06:44

Voir si le XDT (web.config) transformer moteur peut vous aider. Actuellement, il est uniquement pris en charge nativement pour les projets web, mais techniquement, rien ne vous empêche de l'utiliser dans d'autres types d'applications. Il existe de nombreux guides sur la façon d'utiliser XDT en éditant manuellement les fichiers du projet, mais j'ai trouvé un plugin qui fonctionne très bien: https://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859

Le plugin aide seulement à configurer la configuration, ce n'est pas nécessaire pour construire et la solution peut être construite sur d'autres machines ou sur un serveur de construction sans que le plugin ou d'autres outils soient nécessaires.

1
répondu TGasdf 2016-02-10 12:13:26

, j'ai résolu ce sujet avec la solution que j'ai trouvé ici: http://www.blackwasp.co.uk/SwitchConfig.aspx

En bref ce qu'ils disent qu'il est: "en ajoutant un événement post-build.[...] Nous devons ajouter ce qui suit:

if "Debug"=="$(ConfigurationName)" goto :nocopy
del "$(TargetPath).config"
copy "$(ProjectDir)\Release.config" "$(TargetPath).config"
:nocopy
0
répondu Janbro 2017-08-23 13:12:23

Après quelques recherches sur la gestion des configs pour le développement et les builds, j'ai décidé de lancer le mien, je l'ai rendu disponible sur bitbucket à: https://bitbucket.org/brightertools/contemplate/wiki/Home

Ces fichiers de configuration multiples pour plusieurs environnements, c'est un outil de remplacement d'entrée de configuration de base qui fonctionnera avec n'importe quel format de fichier basé sur du texte.

J'espère que cela aide.

0
répondu Mark Redman 2017-11-23 07:25:48

J'ai entendu de bonnes choses à propos de SlowCheetah, mais j'ai été incapable de le faire fonctionner. J'ai fait ce qui suit: ajouter une balise am à chacun pour une configuration spécifique.

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
répondu Mike 2018-08-02 19:33:18