共用方式為


System.Reflection.Emit.AssemblyBuilder 類別

本文提供此 API 參考文件的補充備註。

動態元件是使用 反思 ion Emit API 建立的元件。 動態元件可以參考另一個動態或靜態元件中定義的類型。 您可以使用 AssemblyBuilder 在記憶體中產生動態元件,並在相同的應用程式執行期間執行其程式代碼。 在 .NET 9 中,我們新增了一個新的 PersistedAssemblyBuilder ,其中包含反映發出完全受控的實作,可讓您將元件儲存到檔案中。 在 .NET Framework 中,您可以執行動態元件,並將它儲存至檔案。 為了儲存而建立的動態元件稱為持續性元件,而一般記憶體專用元件稱為暫時性可執行元件 在 .NET Framework 中,動態元件可以包含一或多個動態模組。 在 .NET Core 和 .NET 5+中,動態元件只能包含一個動態模組。

您為每個實作建立 AssemblyBuilder 實例的方式不同,但定義模組、類型、方法或列舉以及撰寫 IL 的進一步步驟相當類似。

.NET 中可執行的動態元件

若要取得可執行 AssemblyBuilder 的物件,請使用 AssemblyBuilder.DefineDynamicAssembly 方法。 您可以使用下列其中一種存取模式來建立動態元件:

在定義動態元件且稍後無法變更時,必須在呼叫 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衍生自 AssemblyBuilder 的新類型,並允許將動態元件儲存在 .NET Core 中,請檢查 PersistedAssemblyBuilder 頁面中的使用案例和範例

.NET Framework 中保存的動態元件

在 .NET Framework 中,動態元件和模組可以儲存至檔案。 為了支援這項功能, AssemblyBuilderAccess 列舉會宣告兩個額外的欄位: SaveRunAndSave

當動態元件使用 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 類上的某些方法,例如 GetModulesGetLoadedModules,無法在從 AssemblyBuilder 物件呼叫時正確運作。 您可以載入定義的動態元件,並在載入的元件上呼叫 方法。 例如,若要確保資源模組包含在傳回的模組清單中,請在載入Assembly的物件上呼叫 GetModules 。 如果動態元件包含一個以上的動態模組,則元件的指令清單檔名稱應該符合指定為方法之第一個自變數 DefineDynamicModule 的模組名稱。

使用的動態元件 KeyPair 簽署在元件儲存到磁碟之前無效。 因此,強名稱不適用於暫時性動態元件。

動態元件可以參考另一個元件中定義的類型。 暫時性動態元件可以安全地參考另一個暫時性動態元件、可保存動態元件或靜態元件中定義的類型。 不過,Common Language Runtime 不允許持續性動態模組參考暫時性動態模組中定義的類型。 這是因為當保存的動態模組在儲存至磁碟之後載入時,運行時間無法解析暫時性動態模組中所定義的類型參考。

對遠端應用程式域發出的限制

某些案例需要在遠端應用程式域中建立和執行動態元件。 反思發出不允許將動態元件直接發出至遠端應用程式域。 解決方案是在目前應用程式域中發出動態元件、將發出的動態元件儲存至磁碟,然後將動態元件載入遠端應用程式域。 只有 .NET Framework 才支持遠端和應用程式域。