アセンブリとは
共通言語基盤(Common Language Infrastructure, CLI)において、アセンブリとはコンパイル済みのコードライブラリであり、配置、バージョン管理、セキュリティ管理の単位となるものです。これは、
.NET Frameworkにおける重要な概念であり、アプリケーションを構成する基本的な要素です。
アセンブリの概要
.NET Frameworkの実装では、アセンブリはPE(Portable Executable)形式のファイルとして存在します。アセンブリには主に二つの種類があります。
1.
プロセスアセンブリ(EXE): 実行可能なプログラムを構成するアセンブリです。
2.
ライブラリアセンブリ(DLL): 他のプログラムから再利用可能なコードを提供するアセンブリです。
以前の
.NET Framework(CLR 1.1)では、クラスを外部に公開できるのはライブラリアセンブリのみでしたが、CLR 2.0以降ではこの制限が緩和されました。
重要な点として、
.NETはアセンブリがプロセス(EXE)かライブラリ(DLL)かを判断する際に、ファイルの
拡張子ではなく、アセンブリ内部に設定されたフラグを使用します。したがって、ライブラリアセンブリが `.exe`
拡張子を持つことも技術的に可能です。
アセンブリに格納されるコードは、コンパイルされてCIL(Common Intermediate Language)形式になっており、実行時には仮想実行システム(Virtual Execution System, VES)によって実行されます。
アセンブリは、単一または複数のファイルで構成され、アセンブリ自身を記述するマニフェストや実行コード、リソースなどが含まれます。コードファイルはモジュールと呼ばれ、アセンブリは一つ以上のモジュールから構成されます。
モジュールの作成にはさまざまなプログラミング言語を使用でき、技術的には、複数のプログラミング言語を用いて一つのアセンブリを生成することも可能です。ただし、Visual Studioのような開発環境では、通常、一つのモジュールのみを含むアセンブリが作成されます。
アセンブリ名
アセンブリ名は、以下の4つの部分から構成されています。
1.
短縮名: Windowsにおいては、PEファイルから
拡張子を除いたものと等しくなります。
2.
カルチャ: RFC 1766(
IETF言語タグ)に規定されたロケールの識別子です。通常、プロセスアセンブリとライブラリアセンブリはニュートラルカルチャ(特定の言語や地域に依存しない)であるべきで、カルチャ情報はサテライトアセンブリでのみ使用されるべきです。
3.
バージョン: 4つの数値(MajorVersion、MinorVersion、BuildNumber、Revision)をドット(`.`)で連結した形式です。
4.
公開キートークン: アセンブリに署名された秘密鍵に対応する公開鍵の64ビットハッシュです。公開キートークンが指定されたアセンブリ名を厳密名と呼びます。公開キートークンはアセンブリ名の重複を防ぐために使用されます。これにより、ファイル名が同じでも、
.NETは異なるアセンブリを区別できます。
しかし、Windowsの
ファイルシステムはファイル名しか認識できないため、同じ短縮名を持つアセンブリを同じフォルダに置くことはできません。これを解決するために、
.NETはGAC(グローバルアセンブリキャッシュ)という仕組みを提供しており、複数のフォルダに置かれたアセンブリをCLRからは同じフォルダにあるものとして認識させることができます。
アセンブリの偽装攻撃を防ぐため、アセンブリは秘密鍵で署名されます。署名する際、アセンブリの重要な部分のハッシュを取り、秘密鍵で暗号化します。このハッシュは公開キーと共にアセンブリ内に格納されます。CLRが厳密名で指定されたアセンブリをロードする際、暗号化されたハッシュを公開キーで復号し、アセンブリのハッシュと比較します。一致すれば、アセンブリに格納された公開キーは署名に使われた秘密鍵に対応するものであると確認できます。
サテライトアセンブリ
通常、アセンブリはニュートラルカルチャのリソースのみを含むべきです。アプリケーションをローカライズする場合(例えばロケールによって異なる文字列を表示する場合)、サテライトアセンブリを使用します。
サテライトアセンブリは、リソースのみを含む特別なアセンブリであり、メインアセンブリに関連付けられます。各サテライトアセンブリは、メインアセンブリ名の末尾に「.resources」を付加した名前を持ちます。例えば、メインアセンブリが `lib.dll` であれば、サテライトアセンブリは `lib.resources.dll` となります。
サテライトアセンブリは非ニュートラルカルチャを持ちますが、Windowsの
ファイルシステムはこれを認識できないため、異なるカルチャを持つサテライトアセンブリを作成するとファイル名が重複してしまいます。これを防ぐために、サテライトアセンブリはアプリケーションフォルダ下のカルチャ別のフォルダに格納されます。例えば、英国
英語(en-GB)のカルチャを持つサテライトアセンブリは、 `en-GB` というサブフォルダに格納されます。
サテライトアセンブリは `System.Resources.ResourceManager` クラスによってロードされます。リソースを取り出すには、開発者はメインアセンブリの情報とリソースの名称を提供する必要があります。 `ResourceManager` クラスは実行環境のロケールを読み取り、それに基づいてサテライトアセンブリの名称と格納フォルダを特定し、ロードします。
Fusion
Windowsの
ファイルシステムはアセンブリのバージョンやカルチャ情報を認識できません。つまり、同じ名前でバージョンだけが異なるアセンブリを一つのフォルダに格納できません。Fusionは、バージョンやカルチャの情報を
ファイルシステム上の名前として使用できるようにする技術です。
Fusionはアセンブリを検索する際、以下の決まった順序で検索を行います。
1.
グローバルアセンブリキャッシュ(GAC): アセンブリが厳密名であれば、最初にGACを検索します。
2.
アプリケーション設定ファイル: 次に、アプリケーションの設定ファイルのリダイレクト情報を参照します。厳密名を持つアセンブリの場合、他のバージョンをロードするように指定したり、ローカル
ファイルシステムやウェブサーバ上のアセンブリを絶対パスで指定できます。厳密名を持たないアセンブリの場合、アプリケーションフォルダ以下のサブフォルダを検索パスとして指定できます。
3.
アプリケーションフォルダ: 次に、アプリケーションフォルダ内にある `.exe` や `.dll`
拡張子を持つアセンブリを検索します。
4.
サブフォルダ: 次に、アセンブリの短縮名と同じ名前を持つサブフォルダ内にある `.exe` および `.dll` ファイルを検索します。
もし、これら全てでもアセンブリが見つからなかった場合、Fusionは例外を投げます。さらに、アセンブリ名やFusionが検索したパスなどの情報が保存され、Fusionログビューワ(fuslogvw)で確認することができます。
まとめ
アセンブリは、
.NET Frameworkアプリケーションの基本的な構成要素であり、コードの配置、バージョン管理、セキュリティ管理を担っています。アセンブリの構造、名前の構成要素、サテライトアセンブリの利用、およびFusionによるアセンブリ検索の仕組みを理解することで、より効率的で堅牢なアプリケーション開発が可能になります。
関連項目
.NET Framework
ダイナミックリンクライブラリ
*
アセンブリ (プログラミング))