it-swarm.com.de

Wie man verschiedene app.config für verschiedene Build-Konfigurationen auswählt

Ich habe ein dll-Projekt, das MSTest-Integrationstests enthält. Auf meinem Computer werden die Tests bestanden, und ich möchte, dass dasselbe auf einem CI-Server geschieht (ich verwende TeamCity). Aber die Tests schlagen fehl, weil ich einige Einstellungen in app.config anpassen muss. Deshalb habe ich mir überlegt, eine separate zweite app.config-Datei zu haben, in der die Einstellungen für den CI-Server gespeichert werden.

Also ich hätte gerne

/Sln 
 /Proj
 app.config (Ich denke, dies wird von VS gefordert) 
 app.Release.config (Dies ist eine eigenständige unabhängige Konfigurationsdatei) 

Wenn ich also in build config auf CI Konfiguration freigeben auswähle, würde ich gerne die Datei app.Release.config anstelle von app.config verwenden

Problem
Dies scheint für einfache Projekte vom Typ .dll nicht einfach zu sein. Für Webprojekte kann ich Webkonfigurationsumwandlungen durchführen. Ich habe einen Hack gefunden, wie man diese Transformationen für ein DLL-Projekt durchführt, aber ich bin kein großer Fan von Hacks.

Frage 
Was ist ein Standardansatz für Tweak app.config-Dateien, abhängig von der Build-Konfiguration für .NET-Projekte (wie Debug, Release, ...)?

106
oleksii

Verwenden Sie SlowCheetah plugin. Weitere Optionen und Details zur Verwendung von SlowCheetah finden Sie hier.

Wie Sie bereits festgestellt haben, gibt es keine standardmäßige und einfache Möglichkeit, verschiedene Konfigurationsdateien für ein Bibliothekstyp (.dll) -Projekt zu verwenden. Der Grund ist, dass der aktuelle Gedanke lautet: "Sie müssen nicht"! Framework-Entwickler gehen davon aus, dass Sie eine Konfiguration für die ausführbare Datei benötigen: Sei es eine Konsole, ein Desktop, ein Web, eine mobile App oder etwas anderes. Wenn Sie mit der Konfiguration einer dll beginnen, erhalten Sie möglicherweise etwas, das ich als config hell bezeichnen kann. Sie können (leicht) nicht mehr verstehen, warum diese und diese Variablen solche seltsamen Werte haben, die scheinbar aus dem Nichts kommen.

"Warten Sie", - Sie können sagen, "aber ich brauche das für meine Integration/Unit-Tests und es ist eine Bibliothek!". Und das ist wahr und das können Sie tun (wählen Sie nur eine aus, mischen Sie nicht):

1. SlowCheetah - wandelt die aktuelle Konfigurationsdatei um

Sie können SlowCheetah - ein Visual Studio-Plug-In installieren, das alle einfachen XML-Poking-Vorgänge (oder Umwandlungen) für Sie erledigt. Wie es funktioniert, kurz:

  • Installieren Sie SlowCheetah und starten Sie Visual Studio neu (Visual Studio> Extras> Erweiterungen und Updates ...> Online> Visual Studio Gallery> Suche nach "Slow Cheetah").
  • Definieren Sie Ihre Lösungskonfigurationen (Debug und Release sind standardmäßig vorhanden. Sie können weitere hinzufügen (klicken Sie mit der rechten Maustaste auf die Lösung in Lösungs-Explorer)> Konfiguration Manager ...> Konfiguration der aktiven Lösung> neu ...
  • Fügen Sie bei Bedarf eine Konfigurationsdatei hinzu
  • Klicken Sie mit der rechten Maustaste auf die Konfigurationsdatei> Add Transform
    • Dadurch werden Transformationsdateien erstellt - eine für Ihre Konfiguration
    • Transformationsdateien arbeiten als Injektoren/Mutatoren. Sie finden den benötigten XML-Code in der ursprünglichen Konfigurationsdatei und fügen neue Zeilen ein oder ändern den erforderlichen Wert, je nachdem, was Sie tun

2. Fiddle mit der .proj-Datei - kopiert die gesamte neue Konfigurationsdatei um

Ursprünglich aus hier entnommen. Es ist eine benutzerdefinierte MSBuild-Aufgabe, die Sie in die .proj -Datei von Visual Studio einbetten können. Kopieren Sie den folgenden Code, und fügen Sie ihn in die Projektdatei ein

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

Erstellen Sie nun im Projekt einen Ordner mit dem Namen Config und fügen Sie dort neue Dateien hinzu: App.Debug.config, App.Release.config und so weiter. Abhängig von Ihrer Konfiguration wählt Visual Studio nun die Konfigurationsdatei aus einem Config-Ordner aus und kopiert diese umbenannt in das Ausgabeverzeichnis. Wenn Sie also PatternPA.Test.Integration project und eine Debug config ausgewählt haben, finden Sie im Ausgabeordner nach dem Build eine PatternPA.Test.Integration.dll). config -Datei, die aus Config\App.Debug.config kopiert und anschließend umbenannt wurde.

Dies sind einige Hinweise, die Sie in den Konfigurationsdateien hinterlassen können

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

In Visual Studio können Sie so etwas haben

Project structure

3. Verwenden Sie Skriptdateien außerhalb von Visual Studio

Jedes Build-Tool (wie NAnt , MSBuild ) bietet Funktionen zum Umwandeln der Konfigurationsdatei abhängig von der Konfiguration. Dies ist nützlich, wenn Sie Ihre Lösung auf einer Build-Maschine erstellen, auf der Sie mehr Kontrolle darüber haben müssen, was und wie Sie das Produkt für die Veröffentlichung vorbereiten.

Sie können beispielsweise die Aufgabe der Web Publishing-DLL verwenden, um eine Konfigurationsdatei umzuwandeln

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

Sie können den folgenden Ansatz ausprobieren:

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie Unload Project aus.
  2. Das Projekt wird entladen. Klicken Sie erneut mit der rechten Maustaste auf das Projekt und wählen Sie Edit <IhrProjektname> .csproj .
  3. Jetzt können Sie die Projektdatei in Visual Studio bearbeiten.
  4. Suchen Sie den Ort in der * .csproj-Datei, in der Ihre Anwendungskonfigurationsdatei enthalten ist. Es wird so aussehen:
 <ItemGroup> 
 <Keine Include = "App.config" />
 </ ItemGroup> 
  1. Ersetzen Sie diese Zeilen durch Folgendes:
 <ItemGroup Condition = "'$ (Configuration)' == 'Debug'"> 
 <Keine Include = "App.Debug.config" />
 </ ItemGroup> 

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

Ich habe diesen Ansatz nicht für app.config-Dateien ausprobiert, aber er hat gut mit anderen Elementen von Visual Studio-Projekten funktioniert. Sie können den Erstellungsprozess auf fast beliebige Weise anpassen. Wie auch immer, lassen Sie mich das Ergebnis wissen.

23
VHaravy

Sie sollten ConfigGen in Betracht ziehen. Es wurde für diesen Zweck entwickelt. Auf jeder Bereitstellungsmaschine wird eine Konfigurationsdatei erstellt, die auf einer Vorlagendatei und einer Einstellungsdatei basiert. Ich weiß, dass dies Ihre Frage nicht speziell beantwortet, aber es könnte Ihr Problem lösen.

Anstelle von Debug, Release usw. haben Sie möglicherweise Test, UAT, Production usw. Sie können auch unterschiedliche Einstellungen für jeden Entwicklercomputer haben, sodass Sie eine für Ihren Dev-Computer spezifische Konfiguration generieren und diese ändern können, ohne dass die Bereitstellung eines anderen Benutzers beeinträchtigt wird .

Ein Beispiel für die Verwendung könnte sein ...

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

Wenn Sie dies in Ihre .csproj-Datei einfügen, haben Sie die folgenden Dateien ...

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

... dann wird dies das Ergebnis sein ...

Mit dem ersten Befehl wird eine Konfigurationsdatei für jede in der xls-Datei angegebene Umgebung generiert und im Ausgabeverzeichnis $ (SolutionDir) ConfigGen abgelegt

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

Mit dem zweiten Befehl wird die lokale App.config, die auf Ihrer Dev-Maschine verwendet wird, durch die generierte Konfiguration ersetzt, die durch den lokalen Schalter (-l) und den Dateinamen (-n) angegeben wird.

12
Daniel Dyson

Mit dem gleichen Ansatz wie Romeo habe ich es an Visual Studio 2010 angepasst:

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

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

Hier müssen Sie beide App.config-Dateien in verschiedenen Verzeichnissen (appDebug und appRelease) aufbewahren.

10
tem peru

SlowCheetah und FastKoala aus der VisualStudio Gallery scheinen sehr gute Werkzeuge zu sein, die bei diesem Problem helfen.

Wenn Sie jedoch Add-Ins vermeiden oder die Prinzipien verwenden möchten, die sie in Ihren Build-/Integrationsprozessen ausführlicher implementieren, ist das Hinzufügen zu Ihren msbuild * proj-Dateien eine Kurzbehebung.

Hinweis: Dies ist mehr oder weniger eine Überarbeitung der Antwort von Nr. 2 von @ oleksii.

Dies funktioniert für .exe- und .dll-Projekte:

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

Dies funktioniert für Webprojekte:

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

Beachten Sie, dass dieser Schritt bereits vor dem eigentlichen Build ausgeführt wird. Die Umwandlung der Konfigurationsdatei erfolgt im Projektordner. Damit ist die transformierte web.config beim Debuggen verfügbar (ein Nachteil von SlowCheetah).

Denken Sie daran, dass, wenn Sie den App_Config-Ordner erstellen (oder wie auch immer Sie ihn aufrufen möchten), die verschiedenen Zwischenkonfigurationsdateien über eine Build-Aktion = Keine und In Ausgabeverzeichnis kopieren = Nicht kopieren verfügen sollten.

Dies kombiniert beide Optionen in einem Block. Die entsprechende wird basierend auf Bedingungen ausgeführt. Die TransformXml-Task wird jedoch zuerst definiert:

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

Ich verwende XmlPreprocess-Tool für die Bearbeitung von Konfigurationsdateien. Es verwendet eine Zuordnungsdatei für mehrere Umgebungen (oder mehrere Build-Ziele in Ihrem Fall). Sie können die Zuordnungsdatei mit Excel bearbeiten. Es ist sehr einfach zu bedienen.

3
Ludwo

Prüfen Sie, ob das XDT-Transformationsmodul (web.config) Ihnen helfen kann. Derzeit wird es nur nativ für Webprojekte unterstützt, technisch gesehen hindert Sie nichts daran, es in anderen Anwendungstypen zu verwenden. Es gibt viele Anleitungen zur Verwendung von XDT durch manuelle Bearbeitung der Projektdateien. Ich habe jedoch ein Plugin gefunden, das hervorragend funktioniert: https://visualstudiogallery.msdn.Microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859

Das Plugin hilft nur beim Einrichten der Konfiguration. Es muss nicht erstellt werden, und die Lösung kann auf anderen Computern oder auf einem Build-Server erstellt werden, ohne dass das Plugin oder andere Tools erforderlich sind.

1
TGasdf

Ich habe dieses Thema mit der hier gefundenen Lösung gelöst: http://www.blackwasp.co.uk/SwitchConfig.aspx

Kurz gesagt, was sie dort angeben: "Durch Hinzufügen eines Postbuild-Ereignisses. [...] Wir müssen Folgendes hinzufügen:

if "Debug"=="$(ConfigurationName)" goto :nocopy
del "$(TargetPath).config"
copy "$(ProjectDir)\Release.config" "$(TargetPath).config"
:nocopy
1
Janbro

Ich habe Gutes über SlowCheetah gehört, konnte es aber nicht zum Laufen bringen. Ich habe Folgendes getan: Fügen Sie jeweils ein Tag für eine bestimmte Konfiguration hinzu.

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

Nach einigen Recherchen zum Verwalten von Konfigurationen für Entwicklung und Builds usw. habe ich beschlossen, meine eigenen zu rollen. Ich habe es auf bitbucket verfügbar gemacht unter: https://bitbucket.org/brightertools/contemplate/wiki/Home

Bei diesen mehreren Konfigurationsdateien für mehrere Umgebungen handelt es sich um ein einfaches Ersetzungstool für Konfigurationseinträge, das mit jedem textbasierten Dateiformat funktioniert.

Hoffe das hilft.

0
Mark Redman