|
61 | 61 |
|
62 | 62 | ## Remarks |
63 | 63 |
|
64 | | -A dynamic assembly is an assembly that is created using the Reflection Emit APIs. A dynamic assembly can reference types defined in another dynamic or static assembly. You can use <xref:System.Reflection.Emit.AssemblyBuilder> to generate dynamic assemblies in memory and execute their code during the same application run. In .NET 9 we added a new [PersistedAssemblyBuilder](system-reflection-emit-persistedassemblybuilder.md) with fully managed implementation of reflection emit that allows you save the assembly into a file. In .NET Framework, you can do both—run the dynamic assembly and save it to a file. The dynamic assembly created for saving is called a *persisted* assembly, while the regular memory-only assembly is called *transient* or *runnable*. In .NET Framework, a dynamic assembly can consist of one or more dynamic modules. In .NET Core and .NET 5+, a dynamic assembly can only consist of one dynamic module. |
65 | | -
|
66 | | -The way you create an <xref:System.Reflection.Emit.AssemblyBuilder> instance differs for each implementation, but further steps for defining a module, type, method, or enum, and for writing IL, are quite similar. |
| 64 | +A dynamic assembly is an assembly that is created using the Reflection Emit APIs. A dynamic assembly can reference types defined in another dynamic or static assembly. You can use <xref:System.Reflection.Emit.AssemblyBuilder> to generate dynamic assemblies in memory and execute their code during the same application run. .NET 9 introduced the <xref:System.Reflection.Emit.PersistedAssemblyBuilder> type with a fully managed implementation of reflection emit that allows you to save the assembly to a file. A dynamic assembly can consist of only one dynamic module. |
67 | 65 |
|
68 | 66 | ## Runnable dynamic assemblies in .NET |
69 | 67 |
|
70 | | -To get a runnable <xref:System.Reflection.Emit.AssemblyBuilder> object, use the <xref:System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly*?displayProperty=nameWithType> method. |
71 | | -Dynamic assemblies can be created using one of the following access modes: |
| 68 | +To get a runnable <xref:System.Reflection.Emit.AssemblyBuilder> object, use the <xref:System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly*?displayProperty=nameWithType> method. Dynamic assemblies can be created using one of the following access modes: |
72 | 69 |
|
73 | 70 | - <xref:System.Reflection.Emit.AssemblyBuilderAccess.Run?displayProperty=nameWithType> |
74 | 71 |
|
@@ -103,51 +100,8 @@ public void CreateAndRunAssembly(string assemblyPath) |
103 | 100 | } |
104 | 101 | ``` |
105 | 102 |
|
106 | | -## Persisted dynamic assemblies in .NET |
107 | | -
|
108 | | -In .NET, the <xref:System.Reflection.Emit.PersistedAssemblyBuilder> type, which derives from <xref:System.Reflection.Emit.AssemblyBuilder>, lets you save dynamic assemblies. For more information, see the usage scenarios and examples at [PersistedAssemblyBuilder](system-reflection-emit-persistedassemblybuilder.md). |
109 | | -
|
110 | | -## Persisted dynamic assemblies in .NET Framework |
111 | | -
|
112 | | -In .NET Framework, dynamic assemblies and modules can be saved to files. To support this feature, the <xref:System.Reflection.Emit.AssemblyBuilderAccess> enumeration declares two additional fields: <xref:System.Reflection.Emit.AssemblyBuilderAccess.Save> and <xref:System.Reflection.Emit.AssemblyBuilderAccess.RunAndSave>. |
113 | | -
|
114 | | -The dynamic modules in the persistable dynamic assembly are saved when the dynamic assembly is saved using the <xref:System.Reflection.Emit.AssemblyBuilder.Save*> method. To generate an executable, the <xref:System.Reflection.Emit.AssemblyBuilder.SetEntryPoint*> method must be called to identify the method that is the entry point to the assembly. Assemblies are saved as DLLs by default, unless the <xref:System.Reflection.Emit.AssemblyBuilder.SetEntryPoint*> method requests the generation of a console application or a Windows-based application. |
115 | | -
|
116 | | -The following example demonstrates how to create, save, and run an assembly using .NET Framework. |
117 | | -
|
118 | | -```csharp |
119 | | -public void CreateRunAndSaveAssembly(string assemblyPath) |
120 | | -{ |
121 | | - AssemblyBuilder ab = Thread.GetDomain().DefineDynamicAssembly(new AssemblyName("MyAssembly"), AssemblyBuilderAccess.RunAndSave); |
122 | | - ModuleBuilder mob = ab.DefineDynamicModule("MyAssembly.dll"); |
123 | | - TypeBuilder tb = mob.DefineType("MyType", TypeAttributes.Public | TypeAttributes.Class); |
124 | | - MethodBuilder meb = tb.DefineMethod("SumMethod", MethodAttributes.Public | MethodAttributes.Static, |
125 | | - typeof(int), new Type[] {typeof(int), typeof(int)}); |
126 | | - ILGenerator il = meb.GetILGenerator(); |
127 | | - il.Emit(OpCodes.Ldarg_0); |
128 | | - il.Emit(OpCodes.Ldarg_1); |
129 | | - il.Emit(OpCodes.Add); |
130 | | - il.Emit(OpCodes.Ret); |
131 | | -
|
132 | | - Type type = tb.CreateType(); |
133 | | -
|
134 | | - MethodInfo method = type.GetMethod("SumMethod"); |
135 | | - Console.WriteLine(method.Invoke(null, new object[] { 5, 10 })); |
136 | | - ab.Save("MyAssembly.dll"); |
137 | | -} |
138 | | -``` |
139 | | -
|
140 | | -Some methods on the base <xref:System.Reflection.Assembly> class, such as `GetModules` and `GetLoadedModules`, won't work correctly when called from <xref:System.Reflection.Emit.AssemblyBuilder> objects. You can load the defined dynamic assembly and call the methods on the loaded assembly. For example, to ensure that resource modules are included in the returned module list, call `GetModules` on the loaded <xref:System.Reflection.Assembly> object. If a dynamic assembly contains more than one dynamic module, the assembly's manifest file name should match the module's name that's specified as the first argument to the <xref:System.Reflection.Emit.AssemblyBuilder.DefineDynamicModule*> method. |
141 | | -
|
142 | | -The signing of a dynamic assembly using <xref:System.Reflection.AssemblyName.KeyPair> is not effective until the assembly is saved to disk. So, strong names will not work with transient dynamic assemblies. |
143 | | -
|
144 | | -Dynamic assemblies can reference types defined in another assembly. A transient dynamic assembly can safely reference types defined in another transient dynamic assembly, a persistable dynamic assembly, or a static assembly. However, the common language runtime does not allow a persistable dynamic module to reference a type defined in a transient dynamic module. This is because when the persisted dynamic module is loaded after being saved to disk, the runtime cannot resolve the references to types defined in the transient dynamic module. |
145 | | -
|
146 | | -### Restrictions on emitting to remote application domains |
| 103 | +The <xref:System.Reflection.Emit.PersistedAssemblyBuilder> type, which derives from <xref:System.Reflection.Emit.AssemblyBuilder>, lets you save dynamic assemblies. For more information, see the usage scenarios and examples at <xref:System.Reflection.Emit.PersistedAssemblyBuilder>. |
147 | 104 |
|
148 | | -Some scenarios require a dynamic assembly to be created and executed in a remote application domain. Reflection emit does not allow a dynamic assembly to be emitted directly to a remote application domain. The solution is to emit the dynamic assembly in the current application domain, save the emitted dynamic assembly to disk, and then load the dynamic assembly into the remote application domain. The remoting and application domains are supported only in .NET Framework. |
149 | | -> [!WARNING] |
150 | | -> `AssemblyBuilder` APIs require a fully trusted environment with trusted input, similar to other technologies such as compilers. There are no restrictions other than basic validation for generated IL that the `AssemblyBuilder` can contain. That includes validation for member name, count, and associated metadata, such as custom attributes. |
151 | 105 | ]]></format> |
152 | 106 | </remarks> |
153 | 107 | <example> |
|
0 commit comments