Ini properti kompilasi!
Salah satu hal terpenting yang perlu diketahui adalah bahwa "Versi Spesifik" adalah properti yang berlaku pada waktu kompilasi dan bukan pada saat runtime.
Tentang apa semua ini?
Ketika sebuah proyek dibangun, referensi perakitan proyek perlu diselesaikan untuk menemukan majelis fisik yang harus digunakan oleh sistem pembangunan. Jika pemeriksaan "Versi Spesifik" dilakukan (lihat bagian "Kapan" Versi Spesifik "dicentang?"), Itu mempengaruhi hasil dari proses resolusi perakitan:
- Sistem build menempatkan rakitan fisik yang berpotensi digunakan
- Sistem build membandingkan versi rakitan fisik dengan versi rakitan yang disimpan dalam file .csproj untuk referensi rakitan
- Jika dua versi rakitan persis sama, proses resolusi berhasil dan rakitan fisik yang ditemukan digunakan untuk membangun
- Jika dua versi rakitan tidak cocok, rakitan fisik dibuang dan proses resolusi berlanjut dengan mencari rakitan potensial berikutnya
- Jika tidak ada lagi rakitan fisik potensial, proses resolusi gagal. Ini menghasilkan peringatan kompiler (peringatan MSB3245) yang memberi tahu Anda bahwa referensi tidak dapat diselesaikan.
- Cukup menarik, build kemudian berlanjut! Jika kode tidak memiliki referensi aktual ke majelis, pembangunan berhasil (dengan peringatan yang disebutkan sebelumnya). Jika kode memiliki referensi, build gagal dengan kesalahan yang terlihat seolah-olah kode tersebut menggunakan tipe atau ruang nama yang tidak dikenal. Satu-satunya indikasi mengapa build benar-benar gagal adalah peringatan MSB3245.
Urutan di mana majelis diselesaikan
Urutan di mana proses resolusi rakitan menempatkan majelis potensial tampaknya adalah sebagai berikut:
- Majelis dirujuk oleh
<HintPath>
elemen dalam file .csproj
- Jalur output proyek
- GAC
Perhatikan bahwa jika beberapa versi rakitan ada di GAC, proses resolusi pertama-tama mencoba untuk menyelesaikan ke rakitan dengan versi tertinggi. Ini penting hanya jika pemeriksaan "Versi Khusus" tidak dilakukan.
Kapan "Versi Spesifik" dicentang?
Visual Studio mendasarkan keputusannya apakah akan melakukan pemeriksaan "Versi Spesifik" pada dua bagian informasi yang ditemukan dalam file .csproj:
- Ada atau tidak adanya
<SpecificVersion>
elemen, dan nilainya (jika ada)
- Ada atau tidak adanya informasi versi dalam referensi perakitan
Ini adalah bagaimana referensi perakitan umum dengan informasi versi terlihat seperti:
<Reference Include="Foo, Version=1.2.3.4, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>True</SpecificVersion>
<HintPath>..\..\Bar\Foo.dll</HintPath>
</Reference>
Dan ini adalah bagaimana referensi perakitan terlihat tanpa informasi versi:
<Reference Include="Foo">
[...]
Tabel berikut ini menunjukkan kapan pemeriksaan "Versi Spesifik" dilakukan, dan ketika itu tidak.
| Version information
| Present Not present
----------------------------+------------------------------
<SpecificVersion> |
- Present, has value True | Yes (1) Yes (check always fails) (2)
- Present, has value False | No (3) No (4)
- Not present | Yes (5) No (6)
Yang mengejutkan di sini adalah bahwa tidak ada pemeriksaan yang dilakukan jika keduanya <SpecificVersion>
dan informasi versi tidak ada (kasus 6). Saya akan mengharapkan pemeriksaan dilakukan dan selalu gagal (sama seperti kasus 2) karena dalam pemahaman saya tidak adanya <SpecificVersion>
menyiratkan nilai default "Benar". Ini mungkin kekhasan Visual Studio 2010 di mana saya melakukan tes saya.
Ketika Anda memeriksa properti referensi perakitan di Visual Studio UI (pilih referensi dan tekan F4), nilai yang Anda lihat untuk properti "Versi Spesifik" memberi tahu Anda apakah Visual Studio akan melakukan "Versi Spesifik" atau tidak. memeriksa. Dalam kasus 6 UI akan menampilkan "True", meskipun <SpecificVersion>
elemen tidak ada dalam file .csproj.
Efek samping pada "Salin lokal"
Jika properti "Salin Lokal" diatur ke "Benar" tetapi proses resolusi rakitan gagal karena pemeriksaan "Versi Khusus", tidak ada rakitan yang disalin.
Materi referensi
PublicKeyToken=
bagian yang hilang ). Juga, jika Anda memeriksa tabel menjelang akhir posting saya, Anda dapat melihat bahwa pemeriksaan versi dapat terjadi bahkan jikaVersion=
bagian tersebut hilang dari nama rakitan di .csproj. Pertanyaan 2: Saya berasumsi bahwa nama majelis digunakan untuk perbandingan, ya. Saya tidak akan tahu sumber lain untuk informasi tersebut.<SpecificVersion>
tag dihapus sepenuhnya, yang sebelumnya memiliki nilai False .Ketika Anda menambahkan referensi maka Visual Studio merekam [AssemblyVersion] dari perakitan di file proyek. Ini penting. Jika Anda, katakanlah, membuat perbaikan bug setahun kemudian maka Anda ingin memastikan bahwa Anda membangun kembali proyek dengan versi referensi yang sama persis sehingga itu benar-benar sebuah drop-in. Anda akan mendapatkan kesalahan jika rakitan referensi telah berubah.
Tapi itu tidak selalu diinginkan. Beberapa pemrogram membiarkan peningkatan versi perakitan, menghasilkan versi baru setiap kali mereka membangun kembali. Meskipun antarmuka publik majelis tidak pernah berubah. Beberapa mengkonfigurasi proyek mereka dengan menggunakan Nuget untuk mendapatkan perpustakaan dan membiarkannya secara otomatis memperbarui perpustakaan ketika ada rilis baru yang tersedia. Mereka ingin mengatur properti Versi Khusus untuk Salah untuk menekan kesalahan kompilasi.
Cukup penting untuk memahami konsekuensinya, Anda perlu memindahkan kembali seluruh program untuk menghindari kecelakaan. Ketidakcocokan versi saat runtime crash program dan hanya dapat ditekan dengan
<bindingRedirect>
file .config yang berisiko.sumber
[AssemblyVersion]
ketika majelis tidak ditandatangani nama yang kuat.