Praktik terbaik untuk solusi besar di Visual Studio (2008) [ditutup]

87

Kami memiliki solusi dengan sekitar 100+ proyek, kebanyakan di antaranya C #. Secara alami, butuh waktu lama untuk membuka dan membangun, jadi saya mencari praktik terbaik untuk binatang seperti itu. Sejalan dengan pertanyaan yang saya harap dapat dijawab, adalah:

  • bagaimana cara terbaik menangani referensi antar proyek
    • haruskah "menyalin lokal" aktif atau nonaktif?
  • haruskah setiap proyek dibangun ke foldernya sendiri, atau haruskah mereka semua membangun ke folder keluaran yang sama (semuanya adalah bagian dari aplikasi yang sama)

  • Apakah folder solusi merupakan cara yang baik untuk mengatur barang?

Saya tahu bahwa membagi solusi menjadi beberapa solusi yang lebih kecil adalah sebuah opsi, tetapi itu datang dengan serangkaian refactoring dan membangun sakit kepala sendiri, jadi mungkin kita dapat menyimpannya untuk utas terpisah :-)

Eyvind
sumber
2
Bolehkah saya bertanya mengapa satu solusi membutuhkan 100+ proyek? Apakah mereka masing-masing menciptakan perakitan mereka sendiri?
Neil N
1
Ya, benar, dan masing-masing mewakili fungsionalitas yang terpisah secara logis.
Eyvind
2
@Eyvind - Bukankah itu tujuan kelas dan namespace? Manfaat apa yang diperoleh dari majelis yang terpisah? Saya dapat memikirkan beberapa, seperti peningkatan yang berpotensi lebih kecil dan penggunaan memori (jika beberapa tidak dimuat), tetapi pasti ada biaya untuk memiliki 100+ rakitan untuk dikompilasi dan dikelola.
si618
1
@ Mark Saya merasakan sakit Anda. Kami mencapai 94 proyek di sini. Tidak bisa berbuat banyak sekarang, karena kami harus menghentikan pengembangan pada banyak tim untuk merestrukturisasi. Kami punya 3 proyek EXE yang mereferensikan 91 lainnya. Saya bereksperimen dengan satu folder keluaran yang umum, sejauh ini keuntungannya sangat mengesankan.
Kevin
2
Man, 100+? Itu bukan apa-apa untuk apa yang kita miliki ... mendorong hampir 600 di sini sekarang ...
C Johnson

Jawaban:

41

Anda mungkin tertarik dengan dua artikel MSBuild yang telah saya tulis ini.

MSBuild: Praktik Terbaik Untuk Membuat Build yang Andal, Bagian 1

MSBuild: Praktik Terbaik Untuk Membuat Build yang Andal, Bagian 2

Secara khusus di Bagian 2 terdapat bagian Membangun pohon sumber yang besar yang mungkin ingin Anda lihat.

Untuk menjawab pertanyaan Anda secara singkat di sini:

  • CopyLocal? Pasti matikan ini
  • Bangun ke satu atau banyak folder keluaran? Bangun ke satu folder keluaran
  • Folder solusi? Ini masalah selera.

Sayed Ibrahim Hashimi

Buku Saya: Di Dalam Microsoft Build Engine: Menggunakan MSBuild dan Team Foundation Build

Sayed Ibrahim Hashimi
sumber
Terima kasih man, saya pasti akan memeriksanya!
Eyvind
1
Saya akan mengatakan bahwa saya memiliki buku ini dan itu luar biasa. Ini telah membantu saya mengotomatiskan build TFS saya dan developer lokal membangun dengan sangat ekstensif. Saya sekarang sedang mengerjakan build Incremental, dan buku ini membahas subjeknya dengan sangat dalam. Sepadan dengan harganya. Terima kasih Sayed. Pertahankan kerja bagus.
irperez
Terima kasih irperez atas komentarnya
Sayed Ibrahim Hashimi
2
-1 untuk rekomendasi UNCONDITIONAL untuk menonaktifkan CopyLocal. Set CopyLocal = false dapat menyebabkan masalah yang berbeda selama waktu penerapan. Lihat entri blog saya "JANGAN Ubah" Referensi proyek "Salin Lokal" ke false, kecuali memahami selanjutnya. "( Geekswithblogs.net/mnf/archive/2012/12/09/… )
Michael Freidgeim
Bisakah "membangun ke satu folder keluaran" menyebabkan masalah saat mengompilasi dengan banyak utas?
BrunoLM
9

1 untuk menghemat penggunaan folder solusi untuk membantu mengatur berbagai hal.

1 untuk pembangunan proyek ke foldernya sendiri. Kami awalnya mencoba folder keluaran umum dan ini dapat menyebabkan referensi yang kadaluwarsa dan tidak kentara dan menyakitkan.

FWIW, kami menggunakan referensi proyek untuk solusi, dan meskipun nuget mungkin merupakan pilihan yang lebih baik akhir-akhir ini, telah menemukan svn: eksternal untuk bekerja dengan baik baik untuk pihak ke-3 dan (tipe kerangka kerja) rakitan internal. Biasakan untuk menggunakan nomor revisi tertentu daripada HEAD saat merujuk svn: externals (bersalah seperti yang ditagih :)

si618
sumber
2
+1 Saya juga memiliki masalah dengan solusi folder keluaran umum. Saya tidak mengerti apa artinya "referensi proyek untuk solusi", mohon jelaskan lebih lanjut ...
Mauricio Scheffer
Seperti di kita menggunakan VS-> Tambahkan Referensi-> Proyek, daripada VS-> Tambahkan Referensi-> Jelajahi. Hal kecil yang saya tahu tetapi beberapa orang melakukannya secara berbeda (dan saya pikir ini menyebabkan lebih banyak sakit kepala). Jika Anda melihat teks MSBuild csproj, Anda akan melihat properti ProjectReference alih-alih Referensi.
si618
Jawaban yang menarik! Saya pikir kami berliku-liku di mana Anda zag. Kami tidak memiliki folder solusi sama sekali dan bergantung pada penamaan proyek (proyek diberi nama yang sama dengan namespace). Semua keluaran kita masuk ke dalam satu folder, yang membuat pengaturan pengembang lebih dekat ke penerapan. Jika dependensi disetel dengan benar maka kami tidak memiliki referensi yang kedaluwarsa.
Thomas Bratt
ya, direktori keluaran umum menyebabkan banyak kesulitan, terutama saat menggunakan resharper. Referensi yang ketinggalan zaman memang.
Florian Doyon
1
@Kevin, sudah beberapa tahun sekarang, tetapi dari memori satu contoh adalah dua proyek yang mereferensikan rakitan yang sama, katakanlah perpustakaan eksternal yang bukan proyek referensi. Semua baik-baik saja ketika mereka menggunakan versi yang sama, tetapi kemudian rilis baru dari pustaka ini keluar, tetapi hanya satu proyek yang memperbarui referensi mereka, versi mana yang digunakan dalam folder keluaran umum?
si618
8

Bongkar proyek yang tidak sering Anda gunakan, dan beli SSD. SSD tidak meningkatkan waktu kompilasi, tetapi Visual Studio menjadi dua kali lebih cepat untuk membuka / menutup / membangun.

Nicolas Dorier
sumber
3
Perlu dicatat bahwa membongkar proyek adalah pengaturan per pengguna, jadi pengembang di tim Anda hanya dapat memuat proyek yang mereka pedulikan. Ini sangat membantu tim kami.
Halaman
Anda dapat menggunakan ekstensi Solution Load Manager visualstudiogallery.msdn.microsoft.com/… untuk menentukan apa yang tidak boleh dimuat secara default
Michael Freidgeim
6

Kami memiliki masalah yang sama karena kami memiliki 109 proyek terpisah untuk ditangani. Untuk menjawab pertanyaan asli berdasarkan pengalaman kami:

1. Bagaimana cara terbaik menangani referensi antar proyek

Kami menggunakan opsi menu konteks 'tambahkan referensi'. Jika 'proyek' dipilih, ketergantungan akan ditambahkan ke file solusi global tunggal kami secara default.

2. Apakah "salin lokal" harus aktif atau nonaktif?

Off dalam pengalaman kami. Penyalinan ekstra hanya menambah waktu pembuatan.

3. Haruskah setiap proyek dibangun ke foldernya sendiri, atau haruskah semuanya dibangun ke folder output yang sama (semuanya adalah bagian dari aplikasi yang sama)

Semua keluaran kita disimpan dalam satu folder bernama 'bin'. Idenya adalah bahwa folder ini sama dengan saat perangkat lunak digunakan. Ini membantu mencegah masalah yang terjadi saat penyiapan pengembang berbeda dari penyiapan penerapan.

4. Apakah folder solusi merupakan cara yang baik untuk mengatur barang?

Tidak dalam pengalaman kami. Struktur folder satu orang adalah mimpi buruk orang lain. Folder yang sangat bersarang hanya menambah waktu yang dibutuhkan untuk menemukan apa pun. Kami memiliki struktur yang benar-benar datar tetapi memberi nama file proyek, rakitan, dan ruang nama kami sama.


Cara kami menyusun proyek bergantung pada satu file solusi. Membangun ini membutuhkan waktu lama, bahkan jika proyeknya sendiri tidak berubah. Untuk membantu dengan ini, kami biasanya membuat file solusi 'set kerja saat ini' lainnya. Setiap proyek yang sedang kami kerjakan ditambahkan ke dalamnya. Waktu pembuatan jauh lebih baik, meskipun satu masalah yang kita lihat adalah bahwa Intellisense gagal untuk tipe yang ditentukan dalam proyek yang tidak ada dalam kumpulan saat ini.

Contoh sebagian dari tata letak solusi kami:

\bin

OurStuff.SLN

OurStuff.App.Administrator
OurStuff.App.Common
OurStuff.App.Installer.Database
OurStuff.App.MediaPlayer
OurStuff.App.Operator
OurStuff.App.Service.Gateway
OurStuff.App.Service.CollectionStation
OurStuff.App.ServiceLocalLauncher
OurStuff.App.StackTester
OurStuff.Auditing
OurStuff.Data
OurStuff.Database
OurStuff.Database.Constants
OurStuff.Database.ObjectModel
OurStuff.Device
OurStuff.Device.Messaging
OurStuff.Diagnostics
...
[etc]
Thomas Bratt
sumber
Bisakah "membangun ke satu folder keluaran" menyebabkan masalah saat mengompilasi dengan banyak utas?
BrunoLM
4

Kami mengerjakan proyek besar serupa di sini. Folder solusi telah terbukti menjadi cara yang baik untuk mengatur berbagai hal, dan kami cenderung membiarkan salinan lokal disetel ke true. Setiap proyek dibangun ke foldernya sendiri, dan kemudian kita tahu untuk setiap proyek yang dapat diterapkan di sana, kita memiliki subset biner yang benar.

Adapun pembukaan waktu dan pembangunan waktu, itu akan sulit diperbaiki tanpa memecah solusi yang lebih kecil. Anda dapat menyelidiki paralelisasi build (google "Parallel MS Build" untuk cara melakukan ini dan mengintegrasikan ke UI) untuk meningkatkan kecepatan di sini. Juga, lihat desainnya dan lihat apakah refactoring beberapa proyek Anda untuk menghasilkan lebih sedikit secara keseluruhan dapat membantu.

David M
sumber
3

Dalam hal meringankan kesulitan pembangunan, Anda dapat menggunakan opsi "Pengelola Konfigurasi ..." untuk build guna mengaktifkan atau menonaktifkan pembuatan project tertentu. Anda dapat memiliki "Proyek [n] Build" yang dapat mengecualikan proyek tertentu dan menggunakannya ketika Anda menargetkan proyek tertentu.

Sejauh 100+ proyek berjalan, saya tahu Anda tidak ingin terpukul dalam pertanyaan ini tentang manfaat mengurangi ukuran solusi Anda, tetapi saya pikir Anda tidak memiliki pilihan lain dalam hal mempercepat waktu muat (dan penggunaan memori) dari devenv.

Michael Meadows
sumber
Hm, apakah ini tidak disukai karena salah, atau hanya karena tidak setuju? Saya bisa hidup dengan yang pertama jika Anda bisa memberi tahu saya alasannya.
Michael Meadows
Setuju, saya tidak suka downvoting tanpa komentar, jadi Michael Anda mendapatkan +1 saya untuk menyeimbangkan persamaan ;-)
si618
2
btw, saya pribadi tidak suka menyia-nyiakan manajemen konfigurasi untuk hal semacam ini. Mengapa? karena jika Anda secara tidak sengaja menjalankan konfigurasi yang dimodifikasi, server build Anda atau pengembang lain akan terpengaruh.
si618
Sepakat. Sebenarnya, masalah yang sama berlaku untuk solusi dengan terlalu banyak proyek. :)
Michael Meadows
3

Apa yang biasanya saya lakukan dengan ini sedikit bergantung pada bagaimana proses "debug" sebenarnya terjadi. Biasanya meskipun saya TIDAK mengatur salinan lokal menjadi true. Saya menyiapkan direktori build untuk setiap proyek untuk menampilkan semuanya ke titik akhir yang diinginkan.

Oleh karena itu setelah setiap build saya memiliki folder yang terisi dengan semua dll dan aplikasi windows / web dan semua item berada di lokasi yang tepat. Salin lokal tidak diperlukan karena dll berakhir di tempat yang tepat pada akhirnya.

Catatan

Di atas berfungsi untuk solusi saya, yang biasanya merupakan aplikasi web dan saya tidak mengalami masalah apa pun dengan referensi, tetapi mungkin saja!

Penjual Mitchel
sumber
3

Kami memiliki masalah serupa. Kami menyelesaikannya menggunakan solusi yang lebih kecil. Kami memiliki solusi utama yang membuka segalanya. Tapi kinerja. itu buruk. Jadi, kami membagi solusi yang lebih kecil menurut jenis pengembang. Jadi, pengembang DB memiliki solusi yang memuat proyek yang mereka pedulikan, pengembang layanan dan pengembang UI hal yang sama. Sangat jarang ketika seseorang harus membuka seluruh solusi untuk menyelesaikan apa yang mereka butuhkan setiap hari. Ini bukan obat mujarab - ada kelebihan dan kekurangannya. Lihat "model multi-solusi" di artikel ini (abaikan bagian tentang menggunakan VSS :)

JP Alioto
sumber
2

Saya pikir dengan solusi sebesar ini, praktik terbaik harus memecahnya. Anda dapat memikirkan "solusi" sebagai tempat untuk menyatukan proyek yang diperlukan dan mungkin bagian lain untuk mengerjakan solusi untuk suatu masalah. Dengan memecah 100+ proyek menjadi beberapa solusi yang dikhususkan untuk mengembangkan solusi hanya untuk sebagian dari keseluruhan masalah, Anda dapat menangani lebih sedikit pada waktu tertentu di sana dengan mempercepat interaksi Anda dengan proyek yang diperlukan dan menyederhanakan domain masalah.

Setiap solusi akan menghasilkan keluaran yang menjadi tanggung jawabnya. Keluaran ini harus memiliki informasi versi yang dapat diatur dalam proses otomatis. Ketika keluaran stabil, Anda dapat memperbarui referensi dalam proyek dan solusi dependen dengan distribusi internal terbaru. Jika Anda masih ingin masuk ke dalam kode dan mengakses sumber, Anda sebenarnya dapat melakukan ini dengan server simbol Microsoft yang dapat digunakan Visual Studio untuk memungkinkan Anda masuk ke rakitan yang direferensikan dan bahkan mengambil kode sumber.

Pengembangan simultan dapat dilakukan dengan menentukan antarmuka di awal dan mengejek rakitan yang sedang dikembangkan sementara Anda menunggu dependensi yang belum lengkap tetapi ingin Anda kembangkan.

Saya menemukan ini sebagai praktik terbaik karena tidak ada batasan seberapa rumit upaya keseluruhan yang dapat Anda peroleh ketika Anda memecahnya secara fisik dengan cara ini. Menempatkan semua proyek ke dalam satu solusi pada akhirnya akan mencapai batas atas.

Semoga informasi ini membantu.

Blake Taylor
sumber
2

Kami memiliki sekitar 60+ proyek dan kami tidak menggunakan file solusi. Kami memiliki campuran proyek C # dan VB.Net. Performa selalu menjadi masalah. Kami tidak mengerjakan semua proyek pada waktu yang sama. Setiap pengembang membuat file solusi mereka sendiri berdasarkan proyek yang mereka kerjakan. File solusi tidak diperiksa ke kontrol sumber kami.

Semua proyek perpustakaan Kelas akan dibangun ke folder CommonBin di root direktori sumber. Executable / Proyek Web dibangun ke folder masing-masing.

Kami tidak menggunakan referensi proyek, melainkan referensi berbasis file dari folder CommonBin. Saya menulis Tugas MSBuild khusus yang akan memeriksa proyek dan menentukan urutan pembuatan.

Kami telah menggunakan ini selama beberapa tahun sekarang dan tidak ada keluhan.

Vasu Balakrishnan
sumber
3
Maukah Anda membagikan tugas msbuild kustom Anda?
andreapier
0

Itu semua berkaitan dengan definisi Anda dan pandangan tentang apa itu solusi dan proyek. Dalam pikiran saya, solusinya hanya itu, pengelompokan proyek yang logis yang menyelesaikan persyaratan yang sangat spesifik. Kami mengembangkan aplikasi Intranet besar. Setiap aplikasi dalam Intranet itu memiliki solusinya sendiri, yang mungkin juga berisi proyek untuk layanan exes atau windows. Dan kemudian kami memiliki kerangka kerja terpusat dengan hal-hal seperti kelas dasar dan pembantu dan httphandlers / httpmodules. Kerangka dasar cukup besar dan digunakan oleh semua aplikasi. Dengan memecah banyak solusi dengan cara ini, Anda mengurangi jumlah proyek yang dibutuhkan oleh sebuah solusi, karena kebanyakan tidak ada hubungannya satu sama lain.

Memiliki banyak proyek dalam sebuah solusi hanyalah desain yang buruk. Seharusnya tidak ada alasan untuk memiliki banyak proyek dalam solusi. Masalah lain yang saya lihat adalah dengan referensi proyek, mereka benar-benar dapat mengacaukan Anda pada akhirnya, terutama jika Anda ingin membagi solusi Anda menjadi yang lebih kecil.

Saran saya adalah melakukan ini dan mengembangkan kerangka kerja terpusat (implementasi Enterprise Library Anda sendiri jika mau). Anda dapat menggunakan GAC untuk membagikannya atau Anda dapat langsung mereferensikan lokasi file sehingga Anda memiliki penyimpanan pusat. Anda juga dapat menggunakan taktik yang sama untuk objek bisnis terpusat.

Jika Anda ingin mereferensikan DLL secara langsung, Anda akan ingin mereferensikannya dalam proyek Anda dengan copy local false (seperti c: \ mycompany \ bin \ mycompany.dll). Sebuah runtime Anda perlu menambahkan beberapa pengaturan ke app.config atau web.config Anda untuk membuatnya mereferensikan file yang tidak ada di GAC atau runtime bin. Pada kenyataannya tidak masalah apakah itu salinan lokal atau tidak, atau jika dll berakhir di tempat sampah atau bahkan di GAC, karena konfigurasi akan menimpa keduanya. Menurut saya, menyalin lokal dan memiliki sistem yang berantakan adalah praktik yang buruk. Anda kemungkinan besar harus menyalin lokal sementara jika Anda perlu men-debug ke salah satu rakitan itu.

Anda dapat membaca artikel saya tentang cara menggunakan DLL secara global tanpa GAC. Saya sangat tidak menyukai GAC terutama karena itu mencegah penyebaran xcopy dan tidak memicu autorestart pada aplikasi.

http://nbaked.wordpress.com/2010/03/28/gac-alternative/

pengguna306031
sumber
0

Setel CopyLocal = false akan mengurangi waktu pembuatan, tetapi dapat menyebabkan masalah yang berbeda selama waktu penerapan.

Ada banyak skenario, ketika Anda perlu memiliki Salin Lokal 'kiri ke True, misalnya Proyek tingkat atas, ketergantungan tingkat kedua, DLL dipanggil dengan refleksi.

Pengalaman saya dengan pengaturan CopyLocal = false tidak berhasil. Lihat ringkasan pro dan kontra di entri blog saya "JANGAN Ubah referensi proyek" Salin Lokal "ke salah, kecuali memahami selanjutnya."

Michael Freidgeim
sumber