アセンブリのバージョンを指定する方法が現在少なくとも3つあることを考えると、.NETでのアセンブリのバージョン管理は混乱を招く可能性があります。
バージョンに関連する3つの主要なアセンブリ属性は次のとおりです。
// 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")]
慣例により、バージョンの4つの部分は、メジャーバージョン、マイナーバージョン、ビルド、およびリビジョンと呼ばれます。
は、個々のアセンブリAssemblyFileVersion
のビルドを一意に識別することを目的としています
通常、アセンブリのバージョンを反映するようにメジャーおよびマイナーAssemblyFileVersionを手動で設定し、ビルドシステムがアセンブリをコンパイルするたびにビルドまたはリビジョン、あるいはその両方をインクリメントします。AssemblyFileVersionを使用すると、アセンブリのビルドを一意に識別できるため、問題をデバッグするための開始点として使用できます。
私の現在のプロジェクトでは、ビルドサーバーにソース管理リポジトリからのチェンジリスト番号をAssemblyFileVersionのビルド部分とリビジョン部分にエンコードさせています。これにより、ビルドサーバーによって生成されたアセンブリについて、アセンブリからそのソースコードに直接マップできます(ソース管理でラベルやブランチを使用したり、リリースされたバージョンのレコードを手動で保持したりする必要はありません)。
このバージョン番号はWin32バージョンリソースに保存されており、アセンブリのWindowsエクスプローラのプロパティページを表示すると表示されます。
CLRは、AssemblyFileVersionを考慮も検査もしません。
はAssemblyInformationalVersion
、製品全体のバージョンを表すことを目的としています
AssemblyInformationalVersionは、製品全体の一貫したバージョン管理を可能にすることを目的としています。これは、おそらく異なるバージョン管理ポリシーを使用して、独立してバージョン管理され、異なるチームによって開発される可能性のある多くのアセンブリで構成される場合があります。
「たとえば、製品のバージョン2.0には、複数のアセンブリが含まれている場合があります。これらのアセンブリの1つは、同じ製品のバージョン1.0で出荷されなかった新しいアセンブリであるため、バージョン1.0としてマークされています。通常、このバージョン番号のメジャー部分とマイナー部分は、製品のパブリックバージョンを表すように設定します。次に、すべてのアセンブリを含む完全な製品をパッケージ化するたびに、ビルドパーツとリビジョンパーツをインクリメントします。」—ジェフリー・リッチター、[C#経由のCLR(第2版)]p。57
CLRは、AssemblyInformationalVersionを気にしたり調べたりしません。
これAssemblyVersion
は、CLRが気にする唯一のバージョンです(ただし、全体を気にしますAssemblyVersion
)
AssemblyVersionは、厳密に名前が付けられたアセンブリにバインドするためにCLRによって使用されます。これは、ビルドされたアセンブリのAssemblyDefマニフェストメタデータテーブルと、それを参照するアセンブリのAssemblyRefテーブルに格納されます。
これは非常に重要です。これは、厳密に名前が付けられたアセンブリを参照すると、そのアセンブリの特定のAssemblyVersionに緊密にバインドされることを意味します。バインディングが成功するには、AssemblyVersion全体が完全に一致している必要があります。たとえば、ビルド時に厳密に名前が付けられたアセンブリのバージョン1.0.0.0を参照しているが、実行時にそのアセンブリのバージョン1.0.0.1しか使用できない場合、バインドは失敗します。(次に、アセンブリバインディングリダイレクトを使用してこれを回避する必要があります。)
全体AssemblyVersion
が一致する必要があるかどうかについての混乱。(はい、そうです。)
アセンブリをロードするために、AssemblyVersion全体が完全に一致する必要があるかどうかについては少し混乱があります。一部の人々は、バインディングが成功するためには、AssemblyVersionのメジャー部分とマイナー部分のみが一致する必要があるという誤った考えの下にあります。これは賢明な仮定ですが、最終的には正しくなく(.NET 3.5以降)、ご使用のバージョンのCLRでこれを確認するのは簡単です。このサンプルコードを実行するだけです。
私のマシンでは、2番目のアセンブリのロードが失敗し、フュージョンログの最後の2行で、理由が完全に明確になっています。
.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.
この混乱の原因は、Microsoftが元々、メジャーバージョンとマイナーバージョンの部分のみを照合することにより、完全なAssemblyVersionのこの厳密な照合をもう少し寛大にすることを意図していたためだと思います。
「アセンブリをロードすると、CLRは、要求されているアセンブリのメジャー/マイナーバージョンと一致する最新のインストール済みサービスバージョンを自動的に検出します。」—ジェフリー・リッチター、[C#経由のCLR(第2版)]p。56
これは1.0CLRのベータ1での動作でしたが、この機能は1.0リリースの前に削除され、.NET2.0で再表示することはできませんでした。
「注:バージョン番号の考え方について説明しました。残念ながら、CLRはバージョン番号をこのように扱いません。[.NET 2.0では]、CLRはバージョン番号を不透明な値として扱い、アセンブリが別のアセンブリのバージョン1.2.3.4に依存している場合、CLRはバージョン1.2.3.4のみを読み込もうとします(バインディングリダイレクトが設定されていない場合) )。ただし、
Microsoftは、CLRのローダーを将来のバージョンで変更して、アセンブリの特定のメジャー/マイナーバージョンの最新のビルド/リビジョンをロードするようにする予定です。。たとえば、CLRの将来のバージョンで、ローダーがアセンブリのバージョン1.2.3.4を検索しようとしていて、バージョン1.2.5.0が存在する場合、ローダーは最新のサービスバージョンを自動的に取得します。これは、CLRのローダーへの非常に歓迎すべき変更です—私は待ちきれません。」—ジェフリー・リッチター、[C#経由のCLR(第2版)]p。164(エンファシスマイン)
この変更はまだ実装されていないので、Microsoftがこの意図を後戻りしたと考えるのは安全だと思います。おそらく、今これを変更するには遅すぎます。これらの計画で何が起こったのかをウェブで検索しようとしましたが、答えが見つかりませんでした。私はまだそれの底に行きたかった。
それで私はジェフ・リクターに電子メールを送り、彼に直接尋ねました—誰かが何が起こったのか知っていれば、それは彼だろうと思いました。
彼は土曜日の朝に12時間以内に返信し、.NET 1.0 Beta 1ローダーが、アセンブリの利用可能な最新のビルドとリビジョンを取得するこの「自動ロールフォワード」メカニズムを実装していることを明らかにしましたが、この動作は.NET1.0が出荷される前に元に戻されました。後でこれを復活させることを目的としていましたが、CLR2.0が出荷される前にはうまくいきませんでした。次に、CLRチームが優先するSilverlightが登場したため、この機能はさらに遅れました。その間、CLR 1.0 Beta 1の時代にいたほとんどの人はその後移動しているので、すでに多大な労力を費やしているにもかかわらず、これが日の目を見ることはありそうにありません。
現在の振る舞いは、ここにとどまっているようです。
また、Jeffとの話し合いから、AssemblyFileVersionは「自動ロールフォワード」メカニズムの削除後にのみ追加されたことにも注意してください。1.0Beta1以降、AssemblyVersionへの変更は顧客にとって重大な変更であったためです。ビルド番号を安全に保存する場所がありません。AssemblyFileVersionは、CLRによって自動的に検査されることはないため、安全な場所です。AssemblyVersionのメジャー/マイナー(ブレーク)部分とビルド/リビジョン(非ブレーク)部分を分離しようとするのではなく、2つの別々のバージョン番号を持ち、別々の意味を持つ方が、おそらくその方が明確です。
結論:変更するときは慎重に考えてくださいAssemblyVersion
他の開発者が参照するアセンブリを出荷する場合、それらのアセンブリのAssemblyVersionを変更する(変更しない)場合は、細心の注意を払う必要があります。AssemblyVersionを変更すると、アプリケーション開発者は新しいバージョンに対して再コンパイルするか(AssemblyRefエントリを更新するため)、アセンブリバインディングリダイレクトを使用してバインディングを手動でオーバーライドする必要があります。
- 下位互換性を目的としたサービスリリースのAssemblyVersionを変更しないでください。
- 重大な変更があることがわかっているリリースのAssemblyVersionを変更してください。
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")]
興味深いサービス情報がすべて含まれているのはAssemblyFileVersionであり(このバージョンのリビジョン部分で、使用しているService Packがわかります)、AssemblyVersionは退屈な古い2.0.0.0に修正されていることに注意してください。AssemblyVersionを変更すると、mscorlib.dllを参照するすべての.NETアプリケーションが新しいバージョンに対して再コンパイルされます。