2015年5月10日

GAC 内のアセンブリ検索方法

.NET Framework アプリケーションの実行時、参照されている署名付きアセンブリ (DLL) は、まずグローバル アセンブリ キャッシュ (GAC) から検索される。
GAC 内に見つからなかった場合、アプリケーションフォルダや設定ファイルで指定した場所が検索される。

で、GAC 内のアセンブリ検索方法は、少し複雑である。

GAC の実フォルダ(アセンブリの配置場所)は、アセンブリの CLR バージョンによって 2 個所に分かれている。
※ 2015/05/01 現在
CLR 1.0 ~ 2.0
(.NET 3.5 以前)
%windir%\assembly
CLR 4
(.NET 4.0 以降)
%windir%\Microsoft.NET\assembly

アセンブリ検索方法も、実行アプリケーション (exe) の CLR バージョンによって異なる。
(A) CLR 1.0 ~ 2.0 ① を検索
(B) CLR 4 ② → ① の順で検索
※実行ファイルのビルド時に .NET 3.5 以前のアセンブリを参照しても ② から検索
→ アセンブリのランタイムバージョンは考慮されない

(B) ※ の補足。
同じ名前・バージョン番号・公開キーのアセンブリ (TEST.DLL) を .NET 3.5 と 4.5 でビルドして、それぞれGAC にインストールする。
→ ① と ② の両方にアセンブリが置かれる。
TEST.DLL (.NET 3.5) を参照する実行アプリを .NET 4.5 でビルドして実行する。
→ ② が先に検索されるため、実際に参照されるアセンブリは TEST.DLL (.NET 4.5)

このような事態を回避するため、GAC にインストールするアセンブリに複数の CLR バージョンがある場合、それぞれ異なるバージョン番号にしておくのが定石。

ちなみに実際に参照されるアセンブリのパスは、下記で確認できる。

// string クラスがあるアセンブリの配置場所
Console.WriteLine(Assembly.GetAssembly(typeof(string)).Location);

// C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll
// ※ mscorlib.dll は GAC から読み込まれない例外

mscorlib.dll が GAC から読み込まれない理由は下記

0 件のコメント:

コメントを投稿