ILMerge はアセンブリをマージします。たとえば、問題のアセンブリが厳密な名前のアセンブリであり、そのキーを持っていない場合、その署名を壊さずに ILMerge を実行することはできません。つまり、複数のアセンブリをデプロイする必要があります。
ilmerge の代わりに、1 つ以上のアセンブリをリソースとして exe または DLL に埋め込むことができます。次に、実行時にアセンブリが読み込まれるときに、埋め込まれたアセンブリをプログラムで抽出し、読み込んで実行できます。難しそうに聞こえますが、定型コードが少しだけあります。
これを行うには、他のリソース (画像、翻訳ファイル、データなど) を埋め込む場合と同様に、アセンブリを埋め込みます。次に、実行時に呼び出される AssemblyResolver を設定します。スタートアップ クラスの静的コンストラクターで設定する必要があります。コードは非常に単純です。
static NameOfStartupClassHere()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Resolver);
}
static System.Reflection.Assembly Resolver(object sender, ResolveEventArgs args)
{
Assembly a1 = Assembly.GetExecutingAssembly();
Stream s = a1.GetManifestResourceStream(args.Name);
byte[] block = new byte[s.Length];
s.Read(block, 0, block.Length);
Assembly a2 = Assembly.Load(block);
return a2;
}
ResolveEventArgs パラメーターの Name プロパティは、解決するアセンブリの名前です。この名前は、ファイル名ではなく、リソースを参照します。「MyAssembly.dll」という名前のファイルを埋め込み、埋め込まれたリソースを「Foo」と呼ぶ場合、ここで必要な名前は「Foo」です。しかし、それは紛らわしいので、リソースの名前にはアセンブリのファイル名を使用することをお勧めします。アセンブリを適切に埋め込んで名前を付けた場合は、アセンブリ名を使用して GetManifestResourceStream() を呼び出すだけで、アセンブリをそのようにロードできます。とてもシンプルです。
これは、単一の組み込みアセンブリと同様に、複数のアセンブリでも機能します。
実際のアプリでは、そのルーチンでより良いエラー処理が必要になります。たとえば、指定された名前のストリームがない場合はどうでしょうか? 読み取りが失敗した場合はどうなりますか? などしかし、それはあなたに任せています。
アプリケーション コードの残りの部分では、通常どおりアセンブリの型を使用します。
アプリをビルドするときは、通常どおり、問題のアセンブリへの参照を追加する必要があります。コマンド ライン ツールを使用する場合は、csc.exe で /r オプションを使用します。Visual Studio を使用する場合は、プロジェクトのポップアップ メニューで [参照の追加...] を行う必要があります。
実行時に、アセンブリのバージョン チェックと検証は通常どおり機能します。
唯一の違いは分布にあります。アプリを展開または配布するときに、埋め込まれた (および参照された) アセンブリの DLL を配布する必要はありません。メイン アセンブリをデプロイするだけです。他のアセンブリはメインの DLL または EXE に組み込まれているため、配布する必要はありません。