Entwicklerspezifische app.config / web.config-Dateien in Visual Studio

93

Wir haben mehrere .NET-Projekte, in denen wir bestimmte Einstellungen in Konfigurationsdateien speichern.

Jetzt hat jeder Entwickler seine eigenen Konfigurationsdateien, die sich geringfügig unterscheiden (unterschiedliche Verbindungszeichenfolgen für die Verbindung zu lokalen Datenbanken, unterschiedliche WCF- Endpunkte usw.).

Im Moment neigen wir dazu, app / web.config-Dateien auszuchecken und sie an unsere Bedürfnisse anzupassen.

Dies führt zu vielen Problemen, da von Zeit zu Zeit jemand seine eigenen Einstellungen überprüft oder die benutzerdefinierte Konfiguration verliert, wenn er die neueste Version von TFS erhält .

Wie gehen Sie mit solchen Situationen um? Oder haben Sie dieses Problem überhaupt nicht?

twarz01
quelle
10
Ich stimme für die Wiedereröffnung, da dies ein häufiges Problem für Entwickler von Visual Studios ist und direkt die Tools betrifft, die Entwickler verwenden. (daher die Stimmen)
Christian Gollhardt
Einverstanden ist dies ein anhaltendes Problem, da unsere Teamgröße gewachsen ist und verschiedene Lösungsversuche unbefriedigend waren.
DiskJunky

Antworten:

66

Wir verwenden ein System, das mehrere der auf dieser Seite vorhandenen Antworten kombiniert und auf diesen Vorschlag von Scott Hanselman zurückgreift .

Kurz gesagt, wir haben eine gemeinsame app.config / web.config und die meisten spezifischen Einstellungen in einzelnen Dateien, wie in anderen Antworten hier vorgeschlagen. zB für unsere SMTP-Einstellungen enthält die app.config

<system.net>
  <mailSettings>
    <smtp configSource="config\smtp.config" />
  </mailSettings>
</system.net>

Diese Datei befindet sich in der Quellcodeverwaltung. Die einzelnen Dateien sind jedoch nicht wie folgt:

<?xml version="1.0" encoding="utf-8" ?>
<smtp deliveryMethod="Network">
  <network host="127.0.0.1" port="25" defaultCredentials="false" password="" userName ="" />
</smtp>

Hier endet die Geschichte allerdings nicht ganz. Was ist mit neuen Entwicklern oder einer neuen Quellinstallation? Der Großteil der Konfiguration befindet sich nicht mehr in der Quellcodeverwaltung, und es ist schwierig, alle benötigten .config-Dateien manuell zu erstellen. Ich bevorzuge eine Quelle, die zumindest sofort kompiliert werden kann.

Aus diesem Grund behalten wir eine Version der .config-Dateien in der Quellcodeverwaltung mit dem Namen .config.default- Dateien. Ein frischer Quellbaum sieht also so aus:

Alt-Text

Für den Entwickler jedoch nicht wirklich von Nutzen, da sie für Visual Studio nur bedeutungslose Textdateien sind. Daher copy_default_config.batkümmert sich die Batch-Datei darum, einen ersten Satz von .config-Dateien aus den .config.default-Dateien zu erstellen:

@echo off
@REM Makes copies of all .default files without the .default extension, only if it doesn't already exist. Does the same recursively through all child folders.
for /r %%f in (*.default) do (
    if not exist "%%~pnf" (echo Copying %%~pnf.default to %%~pnf & copy "%%f" "%%~pnf" /y)
)
echo Done.

Das Skript kann sicher erneut ausgeführt werden, da Entwickler, die bereits über ihre .config-Dateien verfügen, diese nicht überschreiben lassen. Daher könnte man diese Batch-Datei möglicherweise als Pre-Build-Ereignis ausführen. Die Werte in den Standarddateien sind für eine Neuinstallation möglicherweise nicht genau korrekt, aber sie sind ein vernünftiger Ausgangspunkt.

Letztendlich hat jeder Entwickler einen Ordner mit Konfigurationsdateien, der ungefähr so ​​aussieht:

Alt-Text

Es mag ein wenig verworren erscheinen, aber es ist definitiv dem Ärger der Entwickler vorzuziehen, die sich gegenseitig auf die Zehen treten.

Gavin
quelle
Warum nicht direkt die Hauptkonfiguration im Repository haben, aber nicht die einzelnen?
Graffic
6
Was für ein Schmerz, wir brauchen eine bessere Lösung dafür. Ich hatte eine ähnliche Methode eingerichtet und hatte es satt, dass sie so zerbrechlich war und immer noch neuen Entwicklern erklärt werden musste.
Jpierson
@Gavin, ich erhalte eine Fehlermeldung, wenn ich versuche, die von Ihnen beschriebene Bat-Datei auszuführen: '∩╗┐ @ echo' wird nicht als interner oder externer Befehl, bedienbares Programm oder Batch-Datei erkannt.
Austin
2
@Austin, Sie scheinen vor dem '@echo' einen nicht druckbaren Müll zu haben, von dem ein Teil das Unicode-Byte-Bestellzeichen ist? Möglicherweise ist beim Kopieren / Einfügen ein Fehler aufgetreten, oder die Batchdatei wird in einer Codierung gespeichert, die nicht richtig gelesen werden kann.
Gavin
21

Verwenden Sie in Ihrer Web.config die Quelle aus anderen Dateien

<configuration>
    <connectionStrings configSource="ConnectionStrings.config" />
...
</configuration>

Behalten Sie die web.config in der Versionskontrolle und tun Sie dies nicht für ConnectionStrings.config. Jetzt haben alle Entwickler eine Datei für die Verbindungszeichenfolge.

Sie können dies für alle Einstellungen tun, die lokal abhängig sind.

Filipe Pinheiro
quelle
1
Das hat bei mir gut funktioniert. Siehe auch: davidgiard.com/2012/05/25/… Die Datei ConnectionStrings.config muss sich im selben Ordner wie die App oder die Webkonfiguration befinden. Außerdem müssen Sie die Eigenschaften für die Ausgabe in "Kopieren, wenn neuer" ändern. Die Datei ConnectionStrings.config benötigt den vollständigen Abschnitt mit öffnenden und schließenden Elementen. Sie müssen auch die Versionskontrolle so einstellen, dass die Datei ignoriert wird, sodass jede benutzerspezifisch ist.
Jeffrey Roughgarden
1
Ich habe die Option <appSettings file = ".."> verwendet, da ich Einstellungen zusammenführen musste
Spikolynn
1
@JeffreyRoughgarden Wenn Sie die Datei ConnectionStrings.config in den Projektmappen-Explorer aufnehmen, muss die Datei nicht im Dateisystem vorhanden sein? Wenn dies der Fall ist, bedeutet dies, dass Sie die Quellcodeverwaltung aktiviert haben. Welches ist das anfängliche Problem, von dem wir wegkommen wollten.
Jez
20

Hier eine Lösung für web.config-Dateien und Visual Studio 2010:

1) Bearbeiten Sie die .csproj-Datei Ihrer Webanwendung manuell, um ein AfterBuildZiel wie das folgende hinzuzufügen :

  <Project>
   ...
    <Target Name="AfterBuild">
      <Copy SourceFiles="web.config" DestinationFiles="obj\$(Configuration)\tempweb.config" />
      <TransformXml Source="obj\$(Configuration)\tempweb.config"
                  Transform="web.$(USERNAME).config"
                  Destination="obj\$(Configuration)\tempweb2.config" />
      <ReadLinesFromFile File="obj\$(Configuration)\tempweb2.config"><Output TaskParameter="Lines" ItemName="TransformedWebConfig"/></ReadLinesFromFile>
      <ReadLinesFromFile File="web.config"><Output TaskParameter="Lines" ItemName="UnTransformedWebConfig"/></ReadLinesFromFile>
      <Copy Condition=" @(UnTransformedWebConfig) != @(TransformedWebConfig) " SourceFiles="obj\$(Configuration)\tempweb2.config" DestinationFiles="web.config" OverwriteReadOnlyFiles="True" />
    </Target>
  </Project>

Dieses Ziel transformiert die Datei Web.config, die dem aktuell angemeldeten Entwickler entspricht - daher die $(USERNAME)Variable -, wobei die entsprechende Datei in 1) erstellt wird. Die lokale Web.config wird nur dann ersetzt, wenn sich der Inhalt bei jedem Build geändert hat (um einen Neustart zu vermeiden), auch wenn die lokale Web.config quellengesteuert ist. Aus diesem Grund ist die OverwriteReadOnlyFilesEinstellung auf True gesetzt. Dieser Punkt ist in der Tat fraglich.

2) Erstellen Sie eine Datei mit dem Namen Web.[developer windows login].configfür jeden Entwickler im Projekt. (In den folgenden Screenshots habe ich beispielsweise zwei Entwickler namens smo und smo2):

Geben Sie hier die Bildbeschreibung ein

Diese Dateien (1 pro Entwickler) können / sollten quellengesteuert sein. Sie sollten nicht als abhängig von der Haupt-Web.config markiert werden, da wir sie einzeln auschecken möchten.

Jede dieser Dateien stellt eine Transformation dar, die auf die Hauptdatei Web.Config angewendet werden soll. Die Transformationssyntax wird hier beschrieben: Web.config-Transformationssyntax für die Bereitstellung von Webanwendungsprojekten . Wir verwenden diese coole XML-Dateitransformationsaufgabe, die mit Visual Studio ausgeliefert wird. Der Zweck dieser Aufgabe ist merge XML - Elemente und Attribute , anstatt die gesamte Datei zu überschreiben.

Hier ist beispielsweise ein Beispiel web.[dev login].config, das eine Verbindungszeichenfolge mit dem Namen "MyDB" unabhängig vom Rest der Datei "Web.config" ändert:

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <connectionStrings>
      <add name="MyDB" 
        connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True" 
        xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
    </connectionStrings>
</configuration>

Diese Lösung ist nicht perfekt, weil:

  • Nach dem Erstellen haben Entwickler möglicherweise lokal eine andere Web.Config als im Quellcodeverwaltungssystem
  • Möglicherweise müssen sie das lokale Schreiben erzwingen, wenn sie eine neue Web.Config vom Quellcodeverwaltungssystem erhalten
  • Entwickler sollten nicht in der web.config auschecken. Es sollte nur wenigen Personen vorbehalten sein.

Zumindest müssen Sie jedoch nur eine eindeutige web.config-Hauptdatei sowie eine Transformationsdatei pro Entwickler verwalten.

Ein ähnlicher Ansatz könnte für App.config-Dateien (nicht für Webdateien) gewählt werden, aber ich habe nicht weiter darauf eingegangen.

Simon Mourier
quelle
Ich habe meine Web.config in Web.base.config umbenannt, eine neue Web.config-Datei erstellt und dann in Schritt 1 von <Copy SourceFiles = "web.config"> in <Copy SourceFiles = "web.base.config" geändert. Auf diese Weise kann ich eine lokale web.config haben, die in der Quellcodeverwaltung ignoriert werden kann.
S. Baggy
Dies ist immer noch nicht ideal, aber ich ziehe es der anderen Lösung vor
JMK
Denken Sie, dass es möglich ist, ein web.default.configWann zu verwenden, web.$(USERNAME).configdas nicht existiert? Vielen Dank übrigens für diese tolle Antwort.
Christian Gollhardt
2

Wir verwenden machine.config, um Unterschiede in web.config zwischen den Umgebungen zu vermeiden.

Darin Dimitrov
quelle
14
Ich möchte lieber vermeiden, dass machine.config
twarz01
0

Wie wäre es, wenn Sie die Datei ignorieren, damit sie nie eingecheckt wird? Ich bin auf ein ähnliches Problem gestoßen und habe der Ignorierliste in Subversion web.config hinzugefügt.

In TFS ist es allerdings etwas schwieriger. In diesem Beitrag erfahren Sie, wie es geht.

Marko
quelle
0

Eine Möglichkeit, dies zu bewältigen, besteht darin, ein System mit Token zu haben und die Werte mithilfe eines Rake-Skripts zu ändern.

Eine rudimentärere Methode könnte darin bestehen, einen Link zu einer AppSettings.config-Datei für alle AppSettings in Ihrer web.config zu haben (ähnlich wie bei Verbindungen), d. H.

<appSettings configSource="_configs/AppSettings.config" />

Lassen Sie dann einen Ordner mit jedem Ihrer Entwickler eine Version in einem Unterordner haben (dh / _configs / dave /). Wenn ein Entwickler an seinem eigenen Code arbeitet, kopiert er ihn aus dem Unterordner in das Stammverzeichnis des verknüpften Ordners.

Sie müssen sicherstellen, dass Sie Änderungen an diesen Dateien mitteilen (es sei denn, Sie tokenisieren). Wenn Sie die Datei AppSettings.config außerhalb der Quellcodeverwaltung halten und nur die einzelnen Entwicklerordner (alle) einchecken, müssen diese den richtigen kopieren.

Ich bevorzuge die Tokenisierung, kann aber schwieriger in Betrieb zu nehmen sein, wenn dies nur eine schnelle Lösung sein soll.

ArtificialGold
quelle
0

Ignorieren Sie die Dateien und haben Sie eine Commom_Web.Config und eine Common_App.Config. Verwenden eines Build-Servers mit kontinuierlicher Integration mit Build-Tasks, die diese beiden in normale Namen umbenennen, damit der Build-Server seine Arbeit erledigen kann.

Arthis
quelle
Dies muss auf
Entwicklungscomputern durchgeführt
Nein, diese Umbenennung sollte auf dem Build-Server erfolgen. Gängige Konfigurationsdateien, die in der Subversion gespeichert werden, sind unabhängig von einem bestimmten Entwickler. Während jeder Entwickler seine persönlichen Konfigurationsdateien ausführt, um sie auf seinem Computer zu entwickeln, ist es ihm egal, sie zu senden, da sie nicht Teil der Subversion sind.
Arthis
Dies wird nicht von Entwicklern unterstützt, die die Anwendung debuggen. Das Stammverzeichnis web.configim Quellordner wird beim Debuggen verwendet. Wenn Sie beispielsweise hinzugefügt web.configzu .gitignoreund entweder Benutzer kopieren erforderlich Commom_Web.Configzu web.configund bearbeiten sie ihre Phantasie, Sie ist Teil des Weges dorthin. Wenn Sie jedoch etwas bearbeiten müssen, das auf allen Computern des Entwicklers gleich ist, z. B. den system.web/compilationAbschnitt oder einen bestimmten Abschnitt appSettings, der überall gleich sein sollte, fällt dieses Schema auseinander.
Binki
0

Wir haben das gleiche Problem und was wir tun, ist

  • Überprüfen Sie die web.config mit Testserver- / Produktionswerten
  • Der Entwickler wechselt zum Windows Explorer und ändert den schreibgeschützten Modus der Datei
  • Bearbeiten Sie die Konfiguration entsprechend ihrer Umgebung.
  • Das Einchecken in die web.config erfolgt nur, wenn sich die Bereitstellungswerte ändern oder ein Konfigurationseintrag hinzugefügt oder gelöscht wird.
  • Dies erfordert eine gute Menge an Kommentaren für jeden Konfigurationseintrag, da er von jedem Entwickler geändert werden muss
Joy George Kunjikkuru
quelle
1
Dies funktioniert möglicherweise besser in Geschäften, in denen die von Ihnen verwendete Quellcodeverwaltung Felder standardmäßig als schreibgeschützt festlegt. Bei anderen, die Subversion verwenden, funktioniert dies möglicherweise nicht so gut. Wir könnten schreibgeschützte Berechtigungen im Repository festlegen, um zu verhindern, dass es festgeschrieben wird. Dies müsste jedoch für jede Konfigurationsdatei für jeden Zweig festgelegt werden.
Jpierson
Für diejenigen von uns, die so etwas wie TFS nicht verwenden, ist es nicht offensichtlich, wie diese Lösung funktionieren könnte. Könnten Sie etwas mehr Hintergrundwissen geben? Müssen Entwickler nicht vorsichtig sein und die Datei nicht versehentlich auschecken?
Binki
-1

Angenommen, Sie verwenden Visual Studio, warum verwenden Sie nicht unterschiedliche Lösungskonfigurationen? Beispiel: Sie können eine Debug-Konfiguration haben, die Web.config.debug verwendet, und eine Release-Konfiguration, die Web.config.release verwendet. Web.config.debug sollte so etwas wie haben

<appSettings file="C:/Standard_Path_To_Configs/Standard_Name_For_Config.config"> 

mit der Datei Standard_Name_For_Config.config, die alle persönlichen Entwicklereinstellungen enthält, während die Version Web.config.release immer die Produktionseinstellungen enthält. Sie können Standardkonfigurationen in einem quellengesteuerten Ordner speichern und von einem neuen Benutzer von dort übernehmen lassen.


quelle
Dann müsste jeder einzelne Benutzer, der jemals zum Projekt beitragen würde, eine eigene Build-Konfiguration haben. Dies scheint nicht skalierbar zu sein und unterstützt keine Projekte, die Beiträge annehmen.
Binki