Mamy kilka projektów .NET, w których przechowujemy określone ustawienia w plikach konfiguracyjnych.
Teraz każdy deweloper będzie miał własne pliki konfiguracyjne, które nieco się różnią (różne parametry połączenia do łączenia się z lokalnymi bazami danych, różne punkty końcowe WCF itp.)
W tej chwili mamy tendencję do sprawdzania plików app / web.config i modyfikowania ich zgodnie z naszymi potrzebami.
Prowadzi to do wielu problemów, ponieważ od czasu do czasu ktoś będzie sprawdzał własne ustawienia lub tracił konfigurację niestandardową podczas pobierania najnowszej wersji z TFS .
Jak radzisz sobie w takich sytuacjach? A może w ogóle nie masz tego problemu?
Odpowiedzi:
Używamy systemu, który łączy kilka istniejących odpowiedzi na tej stronie, a także opiera się na sugestii Scotta Hanselmana .
Krótko mówiąc, mieliśmy wspólny plik app.config / web.config i większość określonych ustawień w poszczególnych plikach, zgodnie z sugestiami innych odpowiedzi tutaj. np. dla naszych ustawień SMTP plik app.config zawiera
<system.net> <mailSettings> <smtp configSource="config\smtp.config" /> </mailSettings> </system.net>
Ten plik znajduje się w kontroli źródła. Jednak poszczególne pliki, takie jak ten, nie są:
<?xml version="1.0" encoding="utf-8" ?> <smtp deliveryMethod="Network"> <network host="127.0.0.1" port="25" defaultCredentials="false" password="" userName ="" /> </smtp>
Jednak to nie koniec historii. A co z nowymi programistami lub nową instalacją źródłową? Większość konfiguracji nie znajduje się już w kontroli źródła, a ręczne tworzenie wszystkich potrzebnych plików .config jest uciążliwe. Wolę mieć źródło, które przynajmniej będzie się kompilować zaraz po wyjęciu z pudełka.
Dlatego przechowujemy wersję plików .config w kontroli źródła o nazwie pliki .config.default . Dlatego świeże drzewo źródłowe wygląda następująco:
Mimo to programista nie ma z tego żadnego pożytku, ponieważ dla programu Visual Studio są to tylko bezsensowne pliki tekstowe. Dlatego plik wsadowy
copy_default_config.bat
dba o utworzenie początkowego zestawu plików .config z plików .config.default:@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.
Skrypt można bezpiecznie ponownie uruchomić, ponieważ programiści, którzy mają już swoje pliki .config, nie będą ich nadpisywać. Dlatego można sobie wyobrazić uruchomienie tego pliku wsadowego jako zdarzenia przed kompilacją. Wartości w plikach .default mogą nie być dokładnie poprawne dla nowej instalacji, ale są rozsądnym punktem wyjścia.
Ostatecznie to, co kończy każdy programista, to folder plików konfiguracyjnych, który wygląda mniej więcej tak:
Może się to wydawać trochę zawiłe, ale zdecydowanie lepiej niż kłopoty programistów nadeptywających sobie nawzajem.
źródło
W swoim pliku Web.config użyj źródła z innych plików
<configuration> <connectionStrings configSource="ConnectionStrings.config" /> ... </configuration>
Zachowaj plik web.config w kontroli wersji i nie rób tego dla ConnectionStrings.config. Teraz wszyscy programiści mają jeden plik dla parametrów połączenia.
Możesz to zrobić dla wszystkich ustawień zależnych od lokalnego.
źródło
Oto rozwiązanie dla plików web.config i programu Visual Studio 2010:
1) Edytuj ręcznie plik .csproj aplikacji internetowej, aby dodać obiekt
AfterBuild
docelowy w następujący sposób:<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>
Ten cel przekształci plik Web.config odpowiadający aktualnie zalogowanemu deweloperowi - stąd
$(USERNAME)
zmienna - z odpowiednim plikiem utworzonym w 1). Zastąpi lokalny plik Web.config tylko wtedy, gdy zawartość ulegnie zmianie (aby uniknąć ponownego uruchomienia) przy każdej kompilacji, nawet jeśli lokalny plik Web.config jest kontrolowany pod kątem źródła, dlatego istniejeOverwriteReadOnlyFiles
jest ustawiony na True. W rzeczywistości ten punkt jest dyskusyjny.2) Utwórz plik nazwany
Web.[developer windows login].config
dla każdego programisty w projekcie. (na przykład na poniższych zrzutach ekranu mam dwóch programistów o nazwach smo i smo2):Te pliki (1 na programistę) mogą / powinny być kontrolowane pod kątem źródła. Nie należy ich oznaczać jako zależnych od głównego pliku Web.config, ponieważ chcemy mieć możliwość sprawdzenia ich indywidualnie.
Każdy z tych plików reprezentuje transformację do zastosowania w głównym pliku Web.Config. Składnia transformacji została opisana tutaj: Składnia transformacji Web.config dla wdrażania projektu aplikacji sieci Web . Używamy ponownie tego fajnego zadania transformacji pliku Xml, które jest dostarczane z programem Visual Studio. Celem tego zadania jest scalanie elementów i atrybutów Xml zamiast nadpisywania całego pliku.
Na przykład, oto przykład,
web.[dev login].config
który zmienia ciąg połączenia o nazwie „MyDB”, niezależnie od pozostałej części pliku Web.config:<?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>
Teraz to rozwiązanie nie jest idealne, ponieważ:
Ale przynajmniej musisz utrzymywać tylko unikalny główny plik web.config oraz jeden plik transformacji na programistę.
Podobne podejście można zastosować w przypadku plików App.config (nie internetowych), ale nie rozwiązywałem tego dalej.
źródło
web.default.config
kiedyweb.$(USERNAME).config
nie istnieje? Dziękuję za tę wspaniałą odpowiedź.Używamy machine.config, aby uniknąć różnic w pliku web.config między środowiskami.
źródło
Co powiesz na zignorowanie pliku, aby nigdy nie został wpisany? Napotkałem podobny problem i dodałem plik web.config do listy ignorowanych w Subversion.
Jednak w TFS jest to trochę trudniejsze, zobacz ten post, jak to zrobić.
źródło
Jednym ze sposobów, w jaki możesz sobie poradzić, jest posiadanie systemu tokenizowanego i użycie skryptu rake do zmiany wartości.
Bardziej podstawową metodą może być utworzenie łącza do pliku AppSettings.config dla wszystkich ustawień AppSettings w pliku web.config (podobnie jak w przypadku połączeń), tj.
<appSettings configSource="_configs/AppSettings.config" />
Następnie niech folder, w którym każdy z twoich programistów będzie miał wersję w podfolderze (np. / _Configs / dave /). Następnie, gdy programista pracuje nad własnym kodem, kopiuje go z podkatalogu do katalogu głównego połączonego folderu.
Musisz upewnić się, że przekazujesz zmiany w tych plikach (chyba że tokenizujesz). Jeśli utrzymasz plik AppSettings.config poza kontrolą źródła i sprawdzisz tylko poszczególne foldery programistów (wszystkie), będą zmuszeni skopiować poprawny.
Wolę tokenizację, ale może być trudniej zacząć działać, jeśli ma to być tylko szybka naprawa.
źródło
Zignoruj pliki i miej Commom_Web.Config i Common_App.Config. Używanie serwera budowania z ciągłą integracją z zadaniami budowania, które zmieniają nazwy tych dwóch na zwykłe, tak aby serwer budowania mógł wykonać swoje zadanie.
źródło
web.config
Podczas debugowania używany jest katalog główny w folderze źródłowym. Jeśli, na przykład, dodaneweb.config
do.gitignore
i albo wymagane użytkownikom kopiowanieCommom_Web.Config
doweb.config
i edytować go do swojej fantazji, jesteś częścią drogi tam. Ale kiedy musisz edytować coś, co jest takie samo na wszystkich komputerach programistów, na przykładsystem.web/compilation
sekcję lub szczegół,appSettings
który powinien być taki sam wszędzie, ten schemat się rozpada.Mamy ten sam problem i to, co robimy
źródło
Zakładając, że korzystasz z programu Visual Studio, dlaczego nie używasz różnych konfiguracji rozwiązań? Na przykład: możesz mieć konfigurację debugowania, która używa Web.config.debug i konfigurację wydania, która używa Web.config.release. Web.config.debug powinien mieć coś takiego jak
<appSettings file="C:/Standard_Path_To_Configs/Standard_Name_For_Config.config">
z plikiem Standard_Name_For_Config.config, który zawiera wszystkie osobiste ustawienia programisty, podczas gdy plik Web.config.release zawsze ma ustawienia produkcyjne. Możesz przechowywać domyślne konfiguracje w jakimś folderze kontrolowanym przez źródła i sprawić, by nowy użytkownik je stamtąd wziął.
źródło