アセンブリ (共通言語基盤)
![]() |
共通言語基盤においてアセンブリ (assembly) とはコンパイルされたコードライブラリのことであり、配置・バージョン管理・セキュリティ管理の単位となる。
概要
[編集]Windowsの.NET Frameworkの実装においては、アセンブリはPE形式ファイルである。アセンブリにはプロセスアセンブリ (EXE) とライブラリアセンブリ (DLL) の二種類がある。CLR 1.1においてはクラスの外部への公開はライブラリアセンブリでのみ可能だったが、CLR 2.0ではこの制限は緩和された。.NETはアセンブリがプロセスかライブラリかを判断するのに拡張子ではなく内部に設定されたフラグを用いる。従って、ライブラリアセンブリが.exe
の拡張子をもつことも可能である。
アセンブリに格納されるコードはコンパイルされてCILの形をとっており、実行時には仮想実行システム (VES) によって実行される。
アセンブリは、1つ以上のファイルからなり、アセンブリ自身を表すマニフェストや実行コード、リソースなどが含まれる。コードファイルはモジュールと呼ばれ、アセンブリは1つ以上のモジュールを含む。モジュールの作成にはさまざまな言語が使用でき、1つのアセンブリを作成するのに複数のプログラミング言語を使用することも技術的に可能である。ただし、Visual Studioは1つのモジュールを含むアセンブリしか作成できず、これは稀である。
アセンブリ名
[編集]アセンブリ名は4つの部分からなる。
- 短縮名
- WindowsにおいてはこれはPEファイル名から拡張子を除いたものに等しい。
- カルチャ
- これはRFC 1766(IETF言語タグ)に規定されたロケールの識別子である。一般に、プロセスアセンブリとライブラリアセンブリはニュートラルカルチャであるべきであり、カルチャはサテライトアセンブリでのみ使用されるべきである。
- バージョン
- これは4つの数値(MajorVersion、MinorVersion、BuildNumber、Revision)をドット (
.
)で連結したものである[1]。 - 公開キートークン
- これはアセンブリに署名された秘密鍵に対応する公開鍵の64ビットハッシュである。公開キートークンが指定されたアセンブリ名を厳密名という。
公開キートークンはアセンブリ名の重複を防ぐために使われる。従って、2つのアセンブリが同じファイル名であった場合でも.NETは両者を区別することができる。しかし、Windowsのファイルシステムはファイル名しか認識できないため、同じ短縮名をもつアセンブリを同じフォルダに置くことはできない。これを解決するために、.NETはGAC (グローバル アセンブリ キャッシュ) という仕組みを用意している。これによって、複数のフォルダに置いたアセンブリをCLRにとっては同じフォルダにあるものとして認識することができる。
アセンブリの偽装攻撃を防ぐために、アセンブリは秘密キーで署名される。アセンブリに署名する際、アセンブリの重要な部分のハッシュをとりそれを秘密キーで暗号化する。このハッシュは公開キーとともにアセンブリ内に格納される。CLRが厳密名で指定されたアセンブリをロードする際、暗号化されたハッシュを公開キーで復号し、それをアセンブリのハッシュと比較する。それらが一致した場合、アセンブリに格納された公開キーは署名に使われた秘密キーに対応するものだということになる。
サテライトアセンブリ
[編集]一般に、アセンブリはニュートラルカルチャのリソースのみを含んでいるべきである。アセンブリをローカライズしたい場合(例えばロケールによって異なった文字列を参照したい場合)、サテライトアセンブリを使う。サテライト (英: satellite) とは「衛星」あるいは「従者」の意味であり、サテライトアセンブリはリソースのみを含む特殊なアセンブリである。サテライトアセンブリはFusion(後述)によってロードされないので、コードを含めるべきではない。その名前が示すように、サテライトアセンブリはメインアセンブリと呼ばれるアセンブリに関連付けられる。各サテライトアセンブリは、メインアセンブリ名の末尾に「.resources」を付加した名前をもつ。例えば、メインアセンブリが「lib.dll」であれば、サテライトアセンブリは「lib.resources.dll」となる。サテライトアセンブリは非ニュートラルカルチャをもつが、Windowsのファイルシステムはこれを認識することはできないので、異なるカルチャをもつサテライトアセンブリを作成するとファイル名が重複してしまう。これを防ぐために、サテライトアセンブリはアプリケーションフォルダ下のカルチャ別のフォルダに格納される。例えば英国英語のカルチャをもつサテライトアセンブリが「lib.resources Version=0.0.0.0 Culture=en-GB PublicKeyToken=null」という名称だったとすると、ファイル「lib.resources.dll」は「en-GB」というサブフォルダに格納される。
サテライトアセンブリはSystem.Resources.ResourceManager
クラスによってロードされる。リソースを取り出すために、開発者はメインアセンブリの情報とリソースの名称を提供しなければならない。ResourceManager
クラスは実行環境のロケールを読み取り、その情報とメインアセンブリ名からサテライトアセンブリ名とそれが格納されたサブフォルダ名を取得する。そしてそこからサテライトアセンブリをロードし、ローカライズされたリソースを取得する。
Fusion
[編集]Windowsのファイルシステムはアセンブリのバージョンやカルチャの情報を認識することができない。つまり、同じ名前でバージョンだけが異なるアセンブリを1つのフォルダに格納することができない。
Fusionはバージョンやカルチャといった情報をファイルシステム上の名前として使用できるようにするための技術である。 Fusionはアセンブリを検索する際、決まった順序に沿って検索を行う。
- アセンブリが厳密名であれば、まずグローバル アセンブリ キャッシュを検索する。
- Fusionは次に、アプリケーションの設定ファイルのリダイレクト情報を見る。アセンブリが厳密名であれば、他のバージョンをロードするよう指定したり、ローカルファイルシステム上やウェブサーバ上のアセンブリを絶対パスで指定したりすることができる。アセンブリが厳密名でなければ、アプリケーションフォルダ以下のサブフォルダを検索パスとして指定することができる。
- Fusionは次にアプリケーションフォルダ内の
.exe
や.dll
の拡張子をもつアセンブリを検索する。 - Fusionは次にアセンブリの短縮名と同じ名前をもつサブフォルダ内にある
.exe
および.dll
ファイルを検索する。
もしこれでもアセンブリを見つけることができなかった場合、Fusionは例外を投げる。さらに、アセンブリ名やFusionが検索したパスなどの情報が保存される。この情報はFusionログビューワ (fuslogvw) で確認できる。