File app.config / web.config spesifik pengembang di Visual Studio

93

Kami memiliki beberapa proyek .NET tempat kami menyimpan pengaturan tertentu dalam file konfigurasi.

Sekarang setiap pengembang akan memiliki file konfigurasi mereka sendiri yang sedikit berbeda (string koneksi berbeda untuk terhubung ke database lokal, titik akhir WCF berbeda , dll.)

Saat ini kami cenderung untuk memeriksa file app / web.config dan memodifikasinya sesuai kebutuhan kami.

Hal ini menyebabkan banyak masalah karena dari waktu ke waktu seseorang akan memeriksa pengaturannya sendiri atau kehilangan konfigurasi kustom ketika mendapatkan versi terbaru dari TFS .

Bagaimana Anda menghadapi situasi seperti ini? Atau tidakkah Anda memiliki masalah ini sama sekali?

twarz01
sumber
10
Saya memberikan suara untuk membuka kembali, karena ini adalah masalah umum bagi pengembang studio visual dan secara langsung melibatkan alat yang digunakan pengembang. (Oleh karena itu suara)
Christian Gollhardt
Setuju, ini adalah masalah yang terus berlanjut karena ukuran tim kami telah bertambah dan berbagai upaya penyelesaian tidak memuaskan.
DiskJunky

Jawaban:

66

Kami menggunakan sistem yang menggabungkan beberapa jawaban yang ada di halaman ini, ditambah dengan saran dari Scott Hanselman ini .

Singkatnya, apa yang kami lakukan adalah memiliki app.config / web.config yang sama, dan memiliki sebagian besar pengaturan khusus dalam file individual, seperti yang disarankan oleh jawaban lain di sini. misalnya untuk pengaturan SMTP kami, app.config berisi

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

File ini ada dalam kendali sumber. Namun, file individual, seperti ini, bukanlah:

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

Itu belum cukup dimana cerita berakhir. Bagaimana dengan pengembang baru, atau instalasi sumber baru? Sebagian besar konfigurasi tidak lagi berada dalam kontrol sumber, dan merepotkan untuk membuat semua file .config yang mereka butuhkan secara manual. Saya lebih suka memiliki sumber yang setidaknya akan dikompilasi langsung dari kotak.

Oleh karena itu kami menyimpan versi file .config di kontrol sumber, bernama file .config.default . Oleh karena itu, pohon sumber segar terlihat seperti ini:

teks alt

Namun, tidak ada gunanya bagi pengembang, karena untuk Visual Studio mereka hanya file teks yang tidak berarti. Oleh karena itu file batch,, copy_default_config.batmenangani pembuatan set awal file .config dari file .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.

Skrip ini dapat dijalankan kembali dengan aman, karena pengembang yang telah memiliki file .config tidak akan menimpanya. Oleh karena itu, seseorang dapat menjalankan file batch ini sebagai acara pra-pembuatan. Nilai dalam file .default mungkin tidak benar-benar tepat untuk penginstalan baru, tetapi ini adalah titik awal yang masuk akal.

Pada akhirnya apa yang akhirnya didapatkan oleh setiap pengembang adalah folder file konfigurasi yang terlihat seperti ini:

teks alt

Ini mungkin tampak sedikit berbelit-belit, tetapi itu pasti lebih disukai daripada kerumitan pengembang yang saling menginjak kaki.

Gavin
sumber
Mengapa tidak memiliki .config utama secara langsung di repositori tetapi tidak secara individual?
lintas
6
Sungguh menyakitkan, kami membutuhkan solusi yang lebih baik untuk ini. Saya telah menyiapkan metode serupa dan bosan karena metode ini begitu rapuh dan masih membutuhkan penjelasan kepada pengembang baru.
jpierson
@Gavin, saya mendapatkan kesalahan jika saya mencoba menjalankan file bat yang telah Anda gariskan: ' @ echo' tidak dikenali sebagai perintah internal atau eksternal, program yang dapat dioperasikan atau file batch.
Austin
2
@Austin, Anda tampaknya memiliki beberapa sampah yang tidak dapat dicetak sebelum '@echo', bagian yang mungkin merupakan tanda urutan byte Unicode? Mungkin ada yang tidak beres saat menyalin / menempel, atau file batch disimpan dalam penyandian yang tidak dapat dibaca dengan benar.
Gavin
21

Di Web.config Anda, gunakan sumber dari file lain

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

Pertahankan web.config dalam kontrol versi dan jangan lakukan untuk ConnectionStrings.config. Sekarang semua pengembang memiliki satu file untuk string koneksi.

Anda dapat melakukan ini untuk semua pengaturan yang bergantung pada lokal.

Filipe Pinheiro
sumber
1
Ini bekerja dengan baik untuk saya. Lihat juga: davidgiard.com/2012/05/25/… File ConnectionStrings.config harus berada dalam folder yang sama dengan konfigurasi aplikasi atau web. Selain itu, Anda harus mengubah propertinya menjadi 'salin jika lebih baru' menjadi keluaran. Dan file ConnectionStrings.config membutuhkan bagian lengkap dengan elemen pembuka dan penutup. Anda juga harus mengatur kontrol versi untuk mengabaikan file sehingga setiap pengguna spesifik.
Jeffrey Roughgarden
1
Saya menggunakan opsi <appSettings file = ".."> karena saya harus menggabungkan pengaturan
Spikolynn
1
@JeffreyRoughgarden Jika Anda menyertakan file ConnectionStrings.config di Solution Explorer, apakah file tersebut tidak harus ada di filesysterm? Dan jika ya, itu berarti Anda telah memeriksanya ke dalam kontrol sumber. Yang merupakan masalah awal yang coba kami hindari.
Jez
20

Berikut solusi untuk file web.config dan Visual Studio 2010:

1) Edit secara manual file .csproj aplikasi web Anda untuk menambahkan AfterBuildTarget seperti ini:

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

Target ini akan mengubah file Web.config sesuai dengan pengembang saat ini yang masuk - oleh karena itu $(USERNAME)variabel -, dengan file terkait dibuat di 1). Ini akan menggantikan Web.config lokal hanya jika konten telah berubah (untuk menghindari restart) di setiap build, bahkan jika Web.config lokal dikontrol oleh sumber, itulah mengapa ada OverwriteReadOnlyFilesset ke True. Hal ini sebenarnya bisa diperdebatkan.

2) Buat file bernama Web.[developer windows login].configuntuk setiap pengembang dalam proyek. (misalnya di tangkapan layar berikut saya memiliki dua pengembang bernama smo dan smo2):

masukkan deskripsi gambar di sini

File-file ini (1 per pengembang) dapat / harus dikontrol sumbernya. Mereka seharusnya tidak ditandai sebagai tergantung pada Web.config utama karena kita ingin dapat memeriksanya satu per satu.

Setiap file ini mewakili transformasi untuk diterapkan ke file Web.Config utama. Sintaks transformasi dijelaskan di sini: Sintaks Transformasi Web.config untuk Penyebaran Proyek Aplikasi Web . Kami menggunakan kembali tugas transformasi file Xml keren ini yang keluar-of-the-box dengan Visual Studio. Tujuan dari tugas ini adalah menggabungkan elemen dan atribut Xml daripada menimpa seluruh file.

Misalnya, berikut adalah contoh web.[dev login].configyang mengubah string koneksi bernama 'MyDB', terlepas dari file Web.config lainnya:

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

Sekarang, solusi ini tidak sempurna karena:

  • setelah membangun, pengembang mungkin memiliki Web.Config yang berbeda secara lokal daripada di sistem kendali sumber
  • mereka mungkin harus memaksa penulisan lokal saat mendapatkan Web.Config baru dari sistem kendali sumber
  • pengembang tidak boleh memeriksa / di web.config utama. Ini harus disediakan untuk beberapa orang.

Tapi setidaknya, Anda hanya perlu memelihara web.config utama yang unik ditambah satu file transformasi per pengembang.

Pendekatan serupa dapat diambil untuk file App.config (bukan web) tetapi saya tidak menjelaskan lebih lanjut.

Simon Mourier
sumber
Saya mengganti nama Web.config saya menjadi Web.base.config, membuat file Web.config baru, lalu mengubah dari <Copy SourceFiles = "web.config"> menjadi <Copy SourceFiles = "web.base.config" pada langkah 1. Dengan melakukan ini, saya dapat memiliki web.config lokal yang dapat diabaikan di kontrol sumber.
S. Baggy
Ini masih tidak ideal tetapi saya lebih suka solusi lain
JMK
Menurut Anda, apakah mungkin menggunakan web.default.configwhen web.$(USERNAME).configtidak ada? Terima kasih atas jawaban yang bagus ini.
Christian Gollhardt
2

Kami menggunakan machine.config untuk menghindari perbedaan web.config di antara lingkungan.

Darin Dimitrov
sumber
14
lebih suka menghindari keharusan mengganti machine.config
twarz01
0

Bagaimana jika mengabaikan file tersebut, sehingga tidak pernah diperiksa? Saya mengalami masalah serupa dan telah menambahkan web.config ke daftar abaikan di Subversion.

Di TFS, ini sedikit lebih sulit, lihat posting ini tentang cara melakukannya.

Marko
sumber
0

Salah satu cara Anda dapat mengatasinya adalah dengan memiliki sistem tokenis dan menggunakan skrip rake untuk mengubah nilainya.

Metode yang lebih sederhana dapat memiliki tautan ke file AppSettings.config untuk semua AppSettings di web.config Anda (mirip dengan koneksi) yaitu

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

Kemudian buat folder dengan masing-masing pengembang Anda memiliki versi dalam sub folder (yaitu / _configs / dave /). Kemudian ketika pengembang mengerjakan kode mereka sendiri, mereka menyalin dari sub folder ke root folder yang ditautkan.

Anda perlu memastikan bahwa Anda mengkomunikasikan perubahan pada file-file ini (kecuali Anda tokenise) Jika Anda menyimpan file AppSettings.config di luar kendali sumber dan hanya memeriksa di folder individual devs (semuanya) maka mereka akan dipaksa untuk menyalin yang benar.

Saya lebih suka tokenisasi tetapi bisa lebih sulit untuk bangun dan berjalan jika ini hanya dimaksudkan untuk perbaikan cepat.

ArtificialGold
sumber
0

Abaikan file dan miliki Commom_Web.Config dan Common_App.Config. Menggunakan server build integrasi berkelanjutan dengan tugas build yang mengganti nama keduanya menjadi nama normal sehingga server build dapat melakukan tugasnya.

Arthis
sumber
ini perlu dilakukan pada mesin dev, sebelum membangun server
twarz01
Tidak, penggantian nama ini harus terjadi di server build. File konfigurasi umum disimpan di subversi, mereka tidak bergantung pada pengembang tertentu. Sedangkan setiap pengembang menjalankan file konfigurasi pribadinya untuk dikembangkan di mesinnya, dan tidak peduli untuk mengirimkannya karena itu bukan bagian dari subversi.
Arthis
Hal yang tidak didukung ini adalah pengembang men-debug aplikasi. Akar web.configdi folder sumber digunakan selama debugging. Jika Anda, misalnya, menambahkan web.configuntuk .gitignoredan baik diperlukan pengguna untuk menyalin Commom_Web.Configke web.configdan mengedit untuk mewah mereka, Anda sedang bagian dari perjalanan ke sana. Tetapi kemudian ketika Anda perlu mengedit sesuatu yang sama di semua mesin pengembang, seperti system.web/compilationbagian atau bagian tertentu appSettingsyang seharusnya sama di mana-mana, skema ini berantakan.
binki
0

Kami memiliki masalah yang sama dan apa yang kami lakukan adalah

  • Periksa di web.config dengan nilai testserver / produksi
  • Pengembang pergi ke windows explorer dan mengubah mode hanya baca file
  • Edit konfigurasi agar sesuai dengan lingkungan mereka.
  • Check in ke web.config hanya terjadi ketika nilai penerapan berubah atau entri konfigurasi apa pun ditambahkan atau dihapus.
  • Ini membutuhkan banyak komentar untuk setiap entri konfigurasi karena perlu diubah oleh setiap pengembang
Joy George Kunjikkuru
sumber
1
Ini mungkin bekerja lebih baik di toko-toko di mana kontrol sumber Anda menggunakan bidang set sebagai Baca Saja secara default tetapi untuk orang lain yang menggunakan Subversion mungkin tidak berfungsi dengan baik. Kita bisa menyetel izin hanya baca di repositori untuk mencegahnya dari berkomitmen namun itu perlu disetel pada setiap file konfigurasi untuk setiap cabang.
jpierson
Bagi kita yang tidak menggunakan sesuatu seperti TFS, tidak jelas bagaimana solusi ini dapat bekerja. Bisakah Anda memberikan sedikit lebih banyak latar belakang? Selain itu, bukankah itu mengharuskan pengembang untuk berhati-hati dan tidak secara tidak sengaja melakukan checkout file?
binki
-1

Dengan asumsi Anda menggunakan Visual Studio, mengapa Anda tidak menggunakan konfigurasi solusi yang berbeda? Misalnya: Anda dapat memiliki konfigurasi Debug yang menggunakan Web.config.debug dan konfigurasi Rilis yang menggunakan Web.config.release. Web.config.debug seharusnya memiliki sesuatu seperti

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

dengan file Standard_Name_For_Config.config yang mendapatkan semua pengaturan pengembang pribadi, sedangkan Web.config.release selalu memiliki pengaturan produksi. Anda dapat menyimpan konfigurasi default di beberapa folder yang dikontrol sumber dan membuat pengguna baru mengambilnya dari sana.


sumber
Kemudian, setiap pengguna yang pernah berkontribusi pada proyek perlu memiliki konfigurasi build mereka sendiri. Ini tampaknya tidak berskala dan tidak mendukung proyek yang menerima kontribusi.
binki