System.Reflection.Emit.AssemblyBuilder クラス
この記事では、この API のリファレンス ドキュメントへの補足的な解説を提供します。
動的アセンブリは、リフレクトion Emit API を使用して作成されるアセンブリです。 動的アセンブリは、別の動的アセンブリまたは静的アセンブリで定義されている型を参照できます。 メモリ内に動的アセンブリを生成し、同じアプリケーションの実行中にコードを実行するために使用 AssemblyBuilder できます。 .NET 9 では、リフレクション出力のフル マネージド実装を備えた新しい PersistedAssemblyBuilder を追加しました。これにより、アセンブリをファイルに保存できます。 .NET Framework では、動的アセンブリを実行してファイルに保存する両方を実行できます。 保存用に作成された動的アセンブリは永続化アセンブリと呼ばれ、通常のメモリのみのアセンブリは一時的または実行可能と呼ばれます。 .NET Framework では、動的アセンブリは 1 つ以上の動的モジュールで構成できます。 .NET Core と .NET 5 以降では、動的アセンブリは 1 つの動的モジュールのみで構成できます。
インスタンスを作成する AssemblyBuilder 方法は実装ごとに異なりますが、モジュール、型、メソッド、または列挙型を定義する手順と IL を記述する手順は非常に似ています。
.NET での実行可能な動的アセンブリ
実行可能オブジェクト AssemblyBuilder を取得するには、メソッドを AssemblyBuilder.DefineDynamicAssembly 使用します。 動的アセンブリは、次のいずれかのアクセス モードを使用して作成できます。
-
によって表される動的アセンブリを AssemblyBuilder 使用して、出力されたコードを実行できます。
AssemblyBuilderAccess.RunAndCollect
によって表される AssemblyBuilder 動的アセンブリは、生成されたコードを実行するために使用でき、ガベージ コレクターによって自動的に再利用されます。
動的アセンブリが定義されていて、後で変更できない場合は、メソッドのAssemblyBuilder.DefineDynamicAssembly呼び出しで適切なAssemblyBuilderAccess値を指定して、アクセス モードを指定する必要があります。 ランタイムは、動的アセンブリのアクセス モードを使用して、アセンブリの内部表現を最適化します。
次の例では、アセンブリを作成して実行する方法を示します。
public void CreateAndRunAssembly(string assemblyPath)
{
AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("MyAssembly"), AssemblyBuilderAccess.Run);
ModuleBuilder mob = ab.DefineDynamicModule("MyModule");
TypeBuilder tb = mob.DefineType("MyType", TypeAttributes.Public | TypeAttributes.Class);
MethodBuilder mb = tb.DefineMethod("SumMethod", MethodAttributes.Public | MethodAttributes.Static,
typeof(int), new Type[] {typeof(int), typeof(int)});
ILGenerator il = mb.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Ret);
Type type = tb.CreateType();
MethodInfo method = type.GetMethod("SumMethod");
Console.WriteLine(method.Invoke(null, new object[] { 5, 10 }));
}
.NET での永続化された動的アセンブリ
から派生した新しいPersistedAssemblyBuilder型では、PersistedAssemblyBuilder ページの使用シナリオと例チェック、動的アセンブリを .NET Core に保存AssemblyBuilderできます。
.NET Framework での永続化された動的アセンブリ
.NET Framework では、動的アセンブリとモジュールをファイルに保存できます。 この機能をサポートするために、列挙体は AssemblyBuilderAccess 2 つの追加フィールドをRunAndSave宣言しますSave。
永続化可能な動的アセンブリ内の動的モジュールは、メソッドを使用して Save 動的アセンブリが保存されるときに保存されます。 実行可能ファイルを生成するには、アセンブリへの SetEntryPoint エントリ ポイントであるメソッドを識別するためにメソッドを呼び出す必要があります。 メソッドがコンソール アプリケーションまたは Windows ベースのアプリケーションの生成を SetEntryPoint 要求しない限り、アセンブリは既定で DLL として保存されます。
次の例では、.NET Framework を使用してアセンブリを作成、保存、および実行する方法を示します。
public void CreateRunAndSaveAssembly(string assemblyPath)
{
AssemblyBuilder ab = Thread.GetDomain().DefineDynamicAssembly(new AssemblyName("MyAssembly"), AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mob = ab.DefineDynamicModule("MyAssembly.dll");
TypeBuilder tb = mob.DefineType("MyType", TypeAttributes.Public | TypeAttributes.Class);
MethodBuilder meb = tb.DefineMethod("SumMethod", MethodAttributes.Public | MethodAttributes.Static,
typeof(int), new Type[] {typeof(int), typeof(int)});
ILGenerator il = meb.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Ret);
Type type = tb.CreateType();
MethodInfo method = type.GetMethod("SumMethod");
Console.WriteLine(method.Invoke(null, new object[] { 5, 10 }));
ab.Save("MyAssembly.dll");
}
基底 Assembly クラスの一部のメソッド (たとえば GetModules
、オブジェクト GetLoadedModules
から AssemblyBuilder 呼び出された場合) は正しく機能しません。 定義された動的アセンブリを読み込み、読み込まれたアセンブリでメソッドを呼び出すことができます。 たとえば、返されたモジュールの一覧にリソース モジュールが含まれていることを確認するには、読み込まれたAssemblyオブジェクトを呼び出GetModules
します。 動的アセンブリに複数の動的モジュールが含まれている場合、アセンブリのマニフェスト ファイル名は、メソッドの最初の引数として指定されているモジュールの名前と一致する DefineDynamicModule 必要があります。
動的アセンブリの署名は、アセンブリ KeyPair がディスクに保存されるまで有効ではありません。 そのため、厳密な名前は、一時的な動的アセンブリでは機能しません。
動的アセンブリは、別のアセンブリで定義されている型を参照できます。 一時的な動的アセンブリは、別の一時的な動的アセンブリ、永続化可能な動的アセンブリ、または静的アセンブリで定義されている型を安全に参照できます。 ただし、共通言語ランタイムでは、永続化可能な動的モジュールが、一時的な動的モジュールで定義されている型を参照することはできません。 これは、永続化された動的モジュールがディスクに保存された後に読み込まれると、ランタイムが一時的な動的モジュールで定義されている型への参照を解決できないためです。
リモート アプリケーションへの出力に関する制限事項メイン
一部のシナリオでは、リモート アプリケーションで動的アセンブリを作成して実行する必要がありますメイン。 リフレクト出力では、動的アセンブリをリモート アプリケーションに直接出力することはできませんメイン。 解決策は、現在のアプリケーションで動的アセンブリを出力しメイン出力された動的アセンブリをディスクに保存してから、動的アセンブリをリモート アプリケーションに読み込みますメイン。 リモート処理とアプリケーションの実行メインは、.NET Framework でのみサポートされます。
.NET