Pertanyaan Apa perbedaan antara AssemblyVersion, AssemblyFileVersion, dan AssemblyInformationalVersion?


Ada tiga versi rakitan atribut. Apa perbedaannya? Apakah tidak apa jika saya gunakan AssemblyVersion dan mengabaikan sisanya?


MSDN mengatakan:

  • AssemblyVersion:

    Menentukan versi perakitan yang diatributkan.

  • AssemblyFileVersion:

    Menginstruksikan kompiler untuk menggunakan nomor versi tertentu untuk sumber daya file versi Win32. Versi file Win32 tidak diperlukan untuk menjadi sama dengan nomor versi perakitan.

  • AssemblyInformationalVersion:

    Menentukan informasi versi tambahan untuk manifes perakitan.


Ini adalah tindak lanjut Apa praktik terbaik untuk menggunakan Atribut Majelis?


766
2017-09-15 16:47


asal


Jawaban:


AssemblyVersion

Di mana rakitan lain yang mereferensikan pertemuan Anda akan terlihat. Jika nomor ini berubah, majelis lain harus memperbarui referensi mereka ke majelis Anda! Itu AssemblyVersion Dibutuhkan.

Saya menggunakan format: Mayoritas Minoritas. Ini akan menghasilkan:

[assembly: AssemblyVersion("1.0")]

AssemblyFileVersion

Digunakan untuk penyebaran. Anda dapat meningkatkan jumlah ini untuk setiap penerapan. Ini digunakan oleh program pengaturan. Gunakan itu untuk menandai rakitan yang memiliki hal yang sama AssemblyVersion, tetapi dihasilkan dari berbagai versi.

Di Windows, ini dapat dilihat di properti file.

Jika memungkinkan, biarkan dibuat oleh MSBuild. The AssemblyFileVersion adalah opsional. Jika tidak diberikan, AssemblyVersion digunakan.

Saya menggunakan format: major.minor.revision.build, di mana saya menggunakan revisi untuk tahap pengembangan (Alfa, Beta, RC dan RTM), paket layanan dan perbaikan terbaru. Ini akan menghasilkan:

[assembly: AssemblyFileVersion("1.0.3100.1242")]

AssemblyInformationalVersion

Versi Produk dari perakitan. Ini adalah versi yang akan Anda gunakan saat berbicara dengan pelanggan atau untuk ditampilkan di situs web Anda. Versi ini bisa berupa string, seperti '1.0 Release Candidate'.

Analisis Kode akan mengeluh tentang hal itu (CA2243) - dilaporkan ke Microsoft (tidak diperbaiki di VS2013).

Itu AssemblyInformationalVersion adalah opsional. Jika tidak diberikan, AssemblyFileVersion digunakan.

Saya menggunakan format: major.minor [revisi sebagai string]. Ini akan menghasilkan:

[assembly: AssemblyInformationalVersion("1.0 RC1")]

822
2017-09-15 17:46



Pembuatan versi rakitan dalam .NET dapat menjadi prospek yang membingungkan mengingat bahwa saat ini ada setidaknya tiga cara untuk menentukan versi untuk rakitan Anda.

Berikut adalah tiga atribut perakitan yang berhubungan dengan versi utama:

// Assembly mscorlib, Version 2.0.0.0
[assembly: AssemblyFileVersion("2.0.50727.3521")]
[assembly: AssemblyInformationalVersion("2.0.50727.3521")]
[assembly: AssemblyVersion("2.0.0.0")]

Dengan konvensi, empat bagian dari versi disebut sebagai Versi Utama, Versi Minor, Membangun, dan Revisi.

Itu AssemblyFileVersion dimaksudkan untuk mengidentifikasi secara unik suatu bangunan perakitan individu

Biasanya Anda secara manual mengatur Major dan Minor AssemblyFileVersion untuk merefleksikan versi rakitan, kemudian menaikkan Build dan / atau Revisi setiap kali sistem build Anda menyusun rakitan. The AssemblyFileVersion harus memungkinkan Anda untuk secara unik mengidentifikasi membangun perakitan, sehingga Anda dapat menggunakannya sebagai titik awal untuk debug masalah apa pun.

Pada proyek saya saat ini, kami memiliki server build yang menyandikan nomor changelist dari repositori kontrol sumber kami ke bagian Build dan Revisi dari AssemblyFileVersion. Ini memungkinkan kita memetakan secara langsung dari perakitan ke kode sumbernya, untuk setiap perakitan yang dihasilkan oleh server build (tanpa harus menggunakan label atau cabang dalam kontrol sumber, atau secara manual menyimpan catatan versi yang dirilis).

Nomor versi ini disimpan dalam sumber daya versi Win32 dan dapat dilihat saat melihat halaman properti Windows Explorer untuk perakitan.

CLR tidak peduli atau memeriksa AssemblyFileVersion.

Itu AssemblyInformationalVersion dimaksudkan untuk mewakili versi seluruh produk Anda

The AssemblyInformationalVersion dimaksudkan untuk memungkinkan versi yang koheren dari seluruh produk, yang mungkin terdiri dari banyak rakitan yang diversi secara independen, mungkin dengan kebijakan versi berbeda, dan berpotensi dikembangkan oleh tim yang berbeda.

“Misalnya, versi 2.0 dari suatu produk   mungkin berisi beberapa rakitan; satu   dari majelis-majelis ini ditandai sebagai   versi 1.0 karena ini adalah rakitan baru   yang tidak dikirim dalam versi 1.0 dari   produk yang sama. Biasanya, Anda mengatur   bagian utama dan kecil dari versi ini   nomor untuk mewakili versi publik   dari produk Anda. Maka Anda kenaikan   bagian membangun dan revisi setiap waktu   Anda mengemas produk lengkap dengan   semua majelisnya. "              - Jeffrey Richter, [CLR via C # (Edisi Kedua)] hal. 57

CLR tidak peduli atau memeriksa AssemblyInformationalVersion.

Itu AssemblyVersion adalah satu-satunya versi yang dipedulikan CLR (tapi peduli tentang keseluruhannya AssemblyVersion)

AssemblyVersion digunakan oleh CLR untuk berikatan dengan majelis yang diberi nama kuat. Ini disimpan dalam tabel metadata manifest AssemblyDef dari rakitan yang dibangun, dan dalam tabel AssemblyRef dari setiap rakitan yang mereferensikannya.

Ini sangat penting, karena itu berarti bahwa ketika Anda merujuk pada sebuah rakitan yang dinamai dengan kuat, Anda terikat erat pada AssemblyVersion tertentu dari rakitan itu. Seluruh AssemblyVersion harus sama persis agar pengikatan berhasil. Sebagai contoh, jika Anda mereferensikan versi 1.0.0.0 dari kumpulan yang dinamai dengan kuat pada waktu-bangun, tetapi hanya versi 1.0.0.1 dari perakitan itu yang tersedia saat runtime, penjilidan akan gagal! (Anda kemudian harus menggunakan ini Assembly Binding Redirection.)

Kebingungan apakah keseluruhan AssemblyVersion harus cocok. (Ya, benar.)

Ada sedikit kebingungan di sekitar apakah seluruh AssemblyVersion harus sama persis agar sebuah assembly dapat dimuat. Beberapa orang berada di bawah keyakinan salah bahwa hanya bagian-bagian Utama dan Kecil dari AssemblyVersion yang harus cocok agar mengikat untuk berhasil. Ini adalah asumsi yang masuk akal, namun pada akhirnya tidak benar (seperti. NET 3.5), dan ini sepele untuk memverifikasi ini untuk versi CLR Anda. Eksekusi saja kode contoh ini.

Di komputer saya, beban perakitan kedua gagal, dan dua baris terakhir dari log fusion membuatnya sangat jelas mengapa:

.NET Framework Version: 2.0.50727.3521
---
Attempting to load assembly: Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f
Successfully loaded assembly: Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f
---
Attempting to load assembly: Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
Assembly binding for  failed:
System.IO.FileLoadException: Could not load file or assembly 'Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, 
PublicKeyToken=0b3305902db7183f' or one of its dependencies. The located assembly's manifest definition 
does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f'

=== Pre-bind state information ===
LOG: User = Phoenix\Dani
LOG: DisplayName = Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
 (Fully-specified)
LOG: Appbase = [...]
LOG: Initial PrivatePath = NULL
Calling assembly : AssemblyBinding, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
LOG: Attempting download of new URL [...].
WRN: Comparing the assembly name resulted in the mismatch: Revision Number
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

Saya pikir sumber kebingungan ini mungkin karena Microsoft awalnya dimaksudkan untuk menjadi sedikit lebih lunak pada pencocokan ketat dari AssemblyVersion penuh, dengan hanya mencocokkan pada bagian versi Major dan Minor:

“Saat memuat perakitan, CLR akan secara otomatis mencari yang terbaru   menginstal versi servis itu   cocok dengan versi mayor / minor dari   perakitan diminta. "               - Jeffrey Richter, [CLR via C # (Edisi Kedua)] hal. 56

Ini adalah perilaku di Beta 1 dari 1.0 CLR, namun fitur ini dihapus sebelum rilis 1.0, dan belum berhasil memunculkan kembali di .NET 2.0:

“Catatan: Saya baru saja menggambarkan bagaimana Anda   harus memikirkan nomor versi.   Sayangnya, CLR tidak memperlakukan   nomor versi dengan cara ini. [Dalam .NET   2.0], CLR memperlakukan nomor versi sebagai nilai buram, dan jika perakitan   tergantung pada versi 1.2.3.4 dari yang lain   perakitan, CLR mencoba memuat   versi 1.2.3.4 saja (kecuali pengikatan   redirection sudah terpasang). Namun,    Microsoft memiliki rencana untuk mengubah   Loader CLR dalam versi masa depan   bahwa itu memuat yang terbaru   membangun / revisi untuk jurusan / minor tertentu   versi perakitan. Sebagai contoh,   pada versi masa depan CLR, jika   loader sedang mencoba mencari versi   1.2.3.4 dari perakitan dan versi 1.2.5.0 ada, loader dengan otomatis mengambil yang terbaru   versi servis. Ini akan menjadi sangat   selamat datang perubahan ke pemuat CLR - I   karena tidak ada yang bisa menunggu. ”               - Jeffrey Richter, [CLR via C # (Edisi Kedua)] hal. 164 (Penekanan   ranjau)

Karena perubahan ini masih belum diterapkan, menurut saya aman untuk mengasumsikan bahwa Microsoft telah melacak kembali maksud ini, dan mungkin sudah terlambat untuk mengubah ini sekarang. Saya mencoba mencari di seluruh web untuk mencari tahu apa yang terjadi dengan rencana ini, tetapi saya tidak dapat menemukan jawaban apa pun. Saya masih ingin sampai ke bagian bawahnya.

Jadi saya mengirim email kepada Jeff Richter dan menanyakannya secara langsung - saya pikir jika ada yang tahu apa yang terjadi, itu adalah dia.

Dia menjawab dalam waktu 12 jam, pada hari Sabtu pagi tidak kurang, dan mengklarifikasi bahwa loader .NET 1.0 Beta 1 memang menerapkan mekanisme 'pengguliran otomatis' ini dengan mengambil Build dan Revisi terbaru dari perakitan, tetapi perilaku ini adalah dikembalikan sebelum .NET 1.0 dikirim. Itu kemudian dimaksudkan untuk menghidupkan kembali ini tetapi tidak membuatnya sebelum pengiriman CLR 2.0. Kemudian datang Silverlight, yang menjadi prioritas untuk tim CLR, jadi fungsi ini tertunda lebih jauh. Sementara itu, sebagian besar orang yang ada di sekitar CLR 1.0 Beta 1 telah pindah, jadi sepertinya ini tidak akan melihat cahaya siang, terlepas dari semua kerja keras yang telah dilakukan.

Perilaku saat ini, tampaknya, ada di sini untuk tinggal.

Hal ini juga perlu dicatat dari diskusi saya dengan Jeff bahwa AssemblyFileVersion hanya ditambahkan setelah penghapusan mekanisme 'automatic roll-forward' - karena setelah 1.0 Beta 1, perubahan apa pun ke AssemblyVersion adalah perubahan besar bagi pelanggan Anda, kemudian ada tidak ada tempat untuk menyimpan nomor build Anda dengan aman. AssemblyFileVersion adalah tempat aman itu, karena tidak pernah otomatis diperiksa oleh CLR. Mungkin lebih jelas seperti itu, memiliki dua nomor versi terpisah, dengan arti terpisah, daripada mencoba membuat pemisahan antara Mayor / Minor (melanggar) dan bagian Build / Revision (non-breaking) dari AssemblyVersion.

Intinya: Pikirkan baik-baik tentang kapan Anda mengubah Anda AssemblyVersion

Akhlaknya adalah jika Anda mengirim rakitan yang akan dijadikan referensi oleh pengembang lain, Anda harus sangat berhati-hati ketika Anda (dan tidak) mengubah AssemblyVersion dari rakitan tersebut. Perubahan apa pun ke AssemblyVersion akan berarti bahwa pengembang aplikasi harus melakukan kompilasi ulang terhadap versi baru (untuk memperbarui entri AssemblyRef tersebut) atau menggunakan pengalihan pengikatan perakitan untuk secara manual menimpa pengikatan.

  • Tidak ubah AssemblyVersion untuk rilis servicing yang dimaksudkan agar kompatibel ke belakang.
  • Melakukan ubah AssemblyVersion untuk rilis yang Anda tahu telah melanggar perubahan.

Coba lihat lagi atribut versi pada mscorlib:

// Assembly mscorlib, Version 2.0.0.0
[assembly: AssemblyFileVersion("2.0.50727.3521")]
[assembly: AssemblyInformationalVersion("2.0.50727.3521")]
[assembly: AssemblyVersion("2.0.0.0")]

Perhatikan bahwa ini adalah AssemblyFileVersion yang berisi semua informasi servis yang menarik (ini adalah bagian Revisi dari versi ini yang memberi tahu Anda Service Pack Anda), sementara AssemblyVersion tetap pada versi 2.0.0.0 yang membosankan. Perubahan apa pun ke AssemblyVersion akan memaksa setiap aplikasi .NET merujuk mscorlib.dll untuk mengkompilasi ulang terhadap versi baru!


541
2018-04-29 12:01



AssemblyVersion cukup banyak tetap internal. NET, sementara AssemblyFileVersion adalah apa yang dilihat Windows. Jika Anda pergi ke properti dari sebuah majelis yang duduk di direktori dan beralih ke tab versi, AssemblyFileVersion adalah apa yang akan Anda lihat di bagian atas. Jika Anda mengurutkan file berdasarkan versi, inilah yang digunakan oleh Explorer.

Itu AssemblyInformationalVersion memetakan ke "Versi Produk" dan dimaksudkan untuk murni "digunakan manusia".

AssemblyVersion tentu saja yang paling penting, tetapi saya tidak akan melewatkannya AssemblyFileVersion, antara. Jika Anda tidak menyediakan AssemblyInformationalVersion, kompiler menambahkannya untuk Anda dengan menghapus bagian "revisi" dari nomor versi Anda dan meninggalkan major.minor.build.


39
2017-09-15 16:51



AssemblyInformationalVersion dan AssemblyFileVersion ditampilkan ketika Anda melihat "Versi" informasi pada file melalui Windows Explorer dengan melihat properti file. Atribut-atribut ini benar-benar dapat dikompilasi menjadi a VERSION_INFO sumber daya yang dibuat oleh kompilator.

AssemblyInformationalVersion adalah nilai "Versi produk". AssemblyFileVersion adalah nilai "File versi".

Itu AssemblyVersion khusus untuk. NET rakitan dan digunakan oleh. NET perakitan loader untuk mengetahui versi perakitan untuk memuat / mengikat pada saat runtime.

Dari ini, satu-satunya yang mutlak diperlukan oleh. NET adalah AssemblyVersion atribut. Sayangnya itu juga dapat menyebabkan sebagian besar masalah ketika itu berubah tanpa pandang bulu, terutama jika Anda kuat menamai majelis Anda.


21
2017-09-15 16:52



Ini perlu diperhatikan beberapa hal lain:

1) Seperti ditunjukkan dalam dialog Windows Explorer Properties untuk file assembly yang dibuat, ada dua tempat yang disebut "Versi file". Yang terlihat di header dialog menunjukkan AssemblyVersion, bukan AssemblyFileVersion.

Di bagian informasi versi lain, ada elemen lain yang disebut "File Version". Di sinilah Anda dapat melihat apa yang dimasukkan sebagai AssemblyFileVersion.

2) AssemblyFileVersion hanyalah teks biasa. Itu tidak harus sesuai dengan pembatasan skema penomoran yang dilakukan oleh AssemblyVersion (<build> <65K, misalnya). Ini bisa menjadi 3,2. <Rilis tag teks>. <Datetime>, jika Anda suka. Sistem build Anda harus mengisi token.

Selain itu, tidak dikenakan pengganti wildcard yang AssemblyVersion. Jika Anda hanya memiliki nilai "3.0.1. *" Di AssemblyInfo.cs, itulah tepatnya yang akan ditampilkan di informasi versi Lain-> Versi File Version.

3) Saya tidak tahu dampaknya terhadap penginstal menggunakan sesuatu selain nomor versi file angka.


7
2017-11-27 22:51



Untuk menjaga agar pertanyaan ini saat ini, ada baiknya menyoroti hal itu AssemblyInformationalVersion digunakan oleh NuGet dan mencerminkan versi paket termasuk sufiks pra-rilis.

Sebagai contoh, AssemblyVersion 1.0.3. * Dikemas dengan asp.net core dotnet-cli

dotnet pack --version-suffix ci-7 src/MyProject

Menghasilkan paket dengan versi 1.0.3-ci-7 yang dapat Anda periksa dengan refleksi menggunakan:

CustomAttributeExtensions.GetCustomAttribute<AssemblyInformationalVersionAttribute>(asm);

6
2018-06-23 04:51



Ketika AssemblyVersion majelis diubah, Jika memiliki nama yang kuat, majelis referensi perlu dikompilasi ulang, jika tidak perakitan tidak memuat! Jika tidak memiliki nama yang kuat, jika tidak secara eksplisit ditambahkan ke file proyek, itu tidak akan disalin ke direktori output ketika membangun sehingga Anda mungkin kehilangan tergantung majelis, terutama setelah membersihkan direktori output.


2
2018-02-17 05:21