2009-01-09 5 views
53

Kennt jemand gute Tools/Dienstprogramme zum Verwalten von Web.Config Dateien zwischen verschiedenen Build/Deployment-Umgebungen?Verwalten komplexer Web.Config-Dateien zwischen Implementierungsumgebungen

Zum Beispiel habe ich ein WCF-Projekt, das in der Entwicklung ich SSL nicht aktivieren möchte, aber ich möchte es in der Produktion aktiviert. Ich möchte verschiedene Logging-Einstellungen, verschiedene DB-Verbindungszeichenfolgen, unterschiedliche Fehlerbehandlung, verschiedene Dateipfade ... Sogar einige verschiedene Unity-Framework-Bindungen (verdrahte Mocks für Komponententests anstelle der realen Objekte für die Bereitstellung).

Die Pflege einzelner Kopien der Web.Config ist ein Problem, denn das Hinzufügen eines neuen Webdienstes bedeutet, dass mehrere Dateien bearbeitet und synchronisiert werden müssen.

Ich habe auch bemerkt, dass, wenn Sie mit der Web.Config zu viel von Hand Muck, Visual Studio wird ersticken, wenn Sie versuchen, den "Add item" Assistenten verwenden, sagen wir, einen neuen Web Service für WCF, da es muss die Web.Config ändern, um den Endpunkt hinzuzufügen, und kann ihn nicht mehr analysieren. Also muss ich aufpassen, die bestehende Web.Config nicht zu entwerten.

Ich dachte auch nur über einige Regex, um Ersatz zu tun und nur ein neues Web.Config in einem Pre-Build-Befehl zu bauen. Das scheint die beste Option bisher zu sein ...

Irgendwelche anderen Ideen? Es scheint, dass dies ein sehr häufiges Problem sein sollte, da die Web.Config wahrscheinlich niemals zwischen Entwicklungs- und Produktionsbereitstellungen identisch sein sollte.


Update:

ich eine schnelle Konsolenanwendung schreiben entschieden, dass alle XML-Dateien in einem bestimmten Verzeichnis nehmen und sie zu einem verschmelzen und nur bestimmte Dateien auf der Grundlage der Name.

So kann ich in einem Verzeichnis machen:

WebConfig_All

<configuration> 
    <configSections> 
    ... 
    </configSections> 
    <system.web> 
    ... 
    </system.web> 
</configuration> 

connectionStrings_Debug

<configuration> 
    <connectionStrings> 
    <add name="connstr" connectionString="...dev..." /> 
    </connectionStrings> 
</configuration> 

connectionStrings_Release

<configuration> 
    <connectionStrings> 
    <add name="connstr" connectionString="...prod..." /> 
    </connectionStrings> 
</configuration> 

Dann mein Kommandozeilen-Tool, führen und in der Konfiguration (Debug, Veröffentlichung, kundenspezifische ...) passieren Und es wird alle Dateien zusammenführen, die _ <Konfiguration> `in _All" or beenden.

So jetzt habe ich 80% meiner Web.Config in einer einzigen WebConfig_All Datei, und die 20% benutzerdefinierte Zeug in separaten Dateien pro Build-Konfiguration. Ich kann dann mein Kommandozeilen-Tool als Pre-Build-Aufgabe in VisualStudio, oder von NAnt, oder wo immer ich will ...

Ich habe auch meine XML-Merge-Logik gut genug Sachen wie zu handhaben:

<x> 
    <y a="1"> 
    <z a="1"/> 
    </y> 
</x> 

merge mit

<x> 
    <y a="1"> 
    <z a="2"/> 
    </y> 
    <y a="2"/> 
</x> 

Ergebnisse in:

<x> 
    <y a="1"> 
    <z a="1"/> 
    <z a="2"/> 
    </y> 
    <y a="2"/> 
</x> 

Blick so weit gut .. . :)


Followup:

Dieses Thema ist ein wenig alt jetzt, also wollte ich darauf hinweisen, dass Visual Studio 2010 verfügt über eine Funktion web.config Transformationen zu tun eingebaut: http://msdn.microsoft.com/en-us/vstudio/Video/ff801895

Natürlich im typischen Microsoft Mode nur 50% der Art und Weise zu implementieren, funktioniert es nur für Web-Projekte mit Web-Deployment. Es ist ein Plugin-Transformationen in anderen Projekten zu ermöglichen, hier zu finden: http://www.hanselman.com/blog/SlowCheetahWebconfigTransformationSyntaxNowGeneralizedForAnyXMLConfigurationFile.aspx

Sie auch ein Tool wie BuildMaster verwenden könnte Konfigurationsdateien verwalten (zusammen mit Builds, Tests, DB-Skripte, etc ...)

Antwort

19

Wir teilen Sie alle länderspezifischen Einstellungen in thier eigene Konfigurationsdatei. Unter der Wurzel der Web-App erstellen wir einen Konfigurationsordner und legen dort die regionsspezifischen Einstellungen fest. Also, welche Dateien unter der Wurzel von config leben, werden abgeholt.

unsere web.config sieht ungefähr so ​​aus:

. 
. 
. 
<appSettings configSource="config\appSettings.config"/> 
<nlog configSource="config\nlog.config"/> 
<applicationSettings> 
    <MyApp.UI.Properties.Settings configSource="config\Settings.APGUI.config"/> 
    <MyApp.BusinessServices.Properties.Settings configSource="config\Settings.Business.config"/> 
    <MyApp.Auditing.Properties.Settings configSource="config\Settings.Auditing.config"/> 
</applicationSettings> 
. 
. 
. 

Wenn wir also das Build-Tool zu dem Freigabebereich bereitstellen wird nur eine Aktion haben Sie die Dateien in der Wurzel der Config mit den Dateien aus dem ersetzen entsprechender Regionsordner. Die Dateistruktur sieht ungefähr so ​​aus:

ZUSäTZLICH: Dies ist, wie die Source-Control-Struktur aussieht, würde die eingesetzte App nur noch das Konfigurationsverzeichnis ohne Unterordner oder Kurs

\Root 
    web.config  
    \Config  
     appsettings.config  
     services.config  
     logging.config  
     \release  
      appsettings.config  
      services.config  
      logging.config  
     \debug 
      appsettings.config  
      services.config  
      logging.config 

Es ist ziemlich sauber und unterstützte durch ein automatisiertes Build-Tool (Kopieren/Ersetzen von Dateien).Der nette Nebeneffekt ist, dass Entwickler verschiedene Varianten erstellen und sie unter Quellcodeverwaltung behalten können, ohne die "echten" Konfigurationen zu beeinflussen.

+0

Ich mag die Verwendung der ConfigSource-Attribut. Vielleicht kann ich das irgendwie einbeziehen. Es wäre schön, wenn VisualStudio sie automatisch zur Build-Zeit übersetzen und die Marcos von den Run-Tools verwenden könnte ... so könnten Sie "configSource = Config \ $ (ConfigurationName) \ My.Config" angeben – CodingWithSpike

+0

Dies ist eine großartige Lösung! Wo ich bin, verwenden die Entwickler Visual Studio für die Entwicklungsarbeit, dann haben wir eine Build-Maschine, die CruiseControl und NAnt verwendet, die die verschiedenen Releases erstellt (Test, Bühne, Produktion, ...). Das ist perfekt für uns, weil wir einfach eine NAnt-Aufgabe erstellen können, um die entsprechenden Konfigurationsdateien auf Basis der zu erstellenden Version zu kopieren (oder Sie könnten MSBuild oder Visual Studio verwenden, um das Gleiche zu tun, wenn es Ihrer Umgebung besser entspricht). –

1

Ich habe traditionsgemäß die verschiedenen web.configs benutzt, wie Sie erwähnten. Es kann ein Schmerz sein, aber es wird durch Dateivergleichswerkzeuge wie BeyoneComapare2 oder KDIff ... gemildert.

+1

Ich liebe Beyond Compare! Eines meiner Top 5 Lieblingswerkzeuge überhaupt. – CodingWithSpike

7

Sie könnten Build-Events verwenden, um Ihre Web-Konfigurationen zu verwalten. Hanselman hat einen guten Artikel darüber.

Grundsätzlich haben Sie alle Ihre verschiedenen web.configs in der Lösung, die Sie dann erstellen (einige) neue Build-Typen. Abhängig vom Buildtyp wird eine web.config über die referenzierte kopiert!

+0

Auch ich mag dieses Setup mit einem Pre-Build-Ereignis in Visual Studio, um die web.config mit der richtigen web.config-Konfiguration (.debug, .release, .deploy) zu überschreiben. Obwohl Sie mehrere Konfigurationsdateien verwalten müssen, ist dies eine saubere und einfache Einrichtung. Übrigens ist es "Hanselman" und nicht "Hanselmen". – PropellerHead

+0

Fehler in der Rechtschreibprüfung behoben! – cgreeno

+0

genau was ich @ zur gleichen Zeit schrieb :) – Cohen

2

Ich verwende gerne eine Build-Aufgabe zu automate Ändern der Konfigurationsdatei für die gewünschte Umgebung.

0

Annoyance:

ich meine kleines cmd Linie app erwähnte XML-Dokumente in meinem ersten Update zu verschmelzen ... Nun zu tun, dass ich XmlDocument nur verwenden, und schließlich nur .Save(), um einen Filestream.

Unfortuantely, sind die Knoten nicht wirklich in einer bestimmten Reihenfolge, und es scheint, .NET erfordert die <configSections> Element das erste Kind des Dokuments sein.

Ich dachte, alle diese schicken Werkzeuge sollten das Leben der Programmierung einfacher machen?

4

Ich benutze dieses Tool: xmlpreprocess

wir halten separate ‚Eigentum‘ Dateien für jede Umgebung, die in der Bereitstellungsskript zusammengeführt werden.

2

Wir verwenden Tags in unseren Konfigurationsdateien, die zum Zeitpunkt der Erstellung ersetzt werden, um die beabsichtigte Implementierungsumgebung wiederzugeben. Ich bin inspiriert von Lavablast blog

Es ist schön, nur eine Vorlage Konfigurationsdatei verwalten zu haben.

Der Nachteil ist, dass Sie nicht einfach benutzerdefinierte "Abschnitte" haben können.

7

Sie wollen die XmlMassUpdate Aufgabe in MSBuildCommunityTasks (das tut, was Sie versuchen, mit dem XML-Konsole App zu tun)

http://msbuildtasks.tigris.org/

es verwenden, wie diese

<XmlMassUpdate Condition=" '@(ConfigTemplateFile)'!='' And '@(ConfigSubstitutionsFile)'!=''" 
    ContentFile="@(ConfigTemplateFile)" 
    SubstitutionsFile="@(ConfigSubstitutionsFile)" 
    MergedFile="@(ConfigFile)" 
    ContentRoot="/configuration" 
    SubstitutionsRoot="/configuration/substitutions/$(Configuration)"/> 
0

Meine Lieblings zwei Möglichkeiten, damit umzugehen sind:

A. Behalten Sie die Einstellungen auf dem Zielgerät * - In Azure zum Beispiel können Sie Anwendungseinstellungen a nd Verbindungszeichenfolgen, die die Werte in web.config überschreiben. (* - oder Ziel-Maschinendefinition, wenn Ihre Infrastrukturkonfiguration dynamisch ist).

B. Machen Sie das Build/Deployment-Tool (TeamCity, Octopus Deploy, usw., VS Team Services) als Teil des Builds und/oder der Bereitstellung die umgebungsspezifischen Werte ein. Moderne Tools unterstützen die Verschlüsselung sensibler Einstellungen.

2

Alte Frage, aber da es einen hohen Rang in der Google-Suche hat, dachte ich, es ist eine gute Idee, die web.config transformation syntax, die has been available since VS2010 hinzuzufügen. Mit diesem Tool können Sie verschiedene web.config-Dateien für verschiedene Builds erstellen (Debug/Release)

Hier ist eine kurze Zusammenfassung, wie Sie zwei Verbindungszeichenfolgen haben - eine für die Entwicklung (Debug-Modus) und eine für die Produktion (Release Modus):

1- Legen Sie Ihre Entwicklungsverbindungszeichenfolge in der Datei web.config fest. Sieht ähnlich aus:

<connectionStrings> 
    <add name="myConnectionString" connectionString="Data Source=TestDBServer; (etc...)" /> 
    </connectionStrings> 

2- Erweitern Sie Ihre Datei web.config und öffnen Sie web.release.

Config

web.config

3- den Replace function Verwenden Sie die Verbindungszeichenfolge mit dem ersetzen, damit Sie für die Produktion soll. Sie können xdt:Locator="Match(name)" Attribut verwenden Sie es von der Verbindungszeichenfolge (myConnectionString) in diesem Beispiel mit dem Namen übereinstimmen:

<connectionStrings> 
    <add name="myConnectionString" xdt:Transform="Replace" xdt:Locator="Match(name)" 
     connectionString="Data Source=ProdDBServer; (etc...)" /> 
    </connectionStrings> 

4- Vorschau der Transformation der web.config-Datei, die während der Release-Build mit der rechten Maustaste verwendet werden Klicken Sie in der Datei web.release.config und wählen Sie Vorschau Transform.

enter image description here

Verwandte Themen