Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Замечание
В этой статье приводятся дополнительные замечания к справочной документации по этому API.
Динамическая сборка — это сборка, создаваемая с помощью API-интерфейсов Reflection Emit. Динамическая сборка может ссылаться на типы, определенные в другой динамической или статической сборке. Вы можете использовать AssemblyBuilder для создания динамических сборок в памяти и выполнения кода во время выполнения того же приложения. В .NET 9 мы добавили новый PersistedAssemblyBuilder с полностью управляемой реализацией на базе Reflection.Emit, которая позволяет вам сохранять сборку в файл. В .NET Framework можно выполнить оба действия: запустить динамическую сборку и сохранить ее в файле. Динамическая сборка, созданная для сохранения, называется сохранённой сборкой, а обычная сборка, существующая только в памяти, называется временной или выполняемой. В .NET Framework динамическая сборка может состоять из одного или нескольких динамических модулей. В .NET Core и .NET 5+ динамическая сборка может состоять только из одного динамического модуля.
Способ создания экземпляра отличается для каждой AssemblyBuilder реализации, но дальнейшие шаги по определению модуля, типа, метода или перечисления, а также для записи IL довольно похожи.
Запускаемые динамические сборки в .NET
Чтобы получить объект AssemblyBuilder runnable, используйте метод AssemblyBuilder.DefineDynamicAssembly. Динамические сборки можно создать с помощью одного из следующих режимов доступа:
-
Динамическая сборка, представленная AssemblyBuilder, может быть использована для выполнения эмитированного кода.
AssemblyBuilderAccess.RunAndCollect
Динамическая сборка, представленная элементом AssemblyBuilder, может использоваться для выполнения сгенерированного кода и автоматически освобождается сборщиком мусора.
Режим доступа необходимо указать, указав соответствующее AssemblyBuilderAccess значение в вызове AssemblyBuilder.DefineDynamicAssembly метода при определении динамической сборки и не может быть изменено позже. Среда выполнения использует режим доступа динамической сборки для оптимизации внутреннего представления сборки.
В следующем примере показано, как создать и запустить сборку:
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
В .NET тип, производный PersistedAssemblyBuilder от AssemblyBuilder, позволяет сохранять динамические сборки. Дополнительные сведения см. в сценариях использования и примерах в PersistedAssemblyBuilder.
Постоянные динамические сборки в .NET Framework
В .NET Framework динамические сборки и модули можно сохранить в файлах. Чтобы поддержать эту функцию, перечисление AssemblyBuilderAccess объявляет два дополнительных поля: Save и RunAndSave.
Динамические модули в сохраняемой динамической сборке сохраняются при сохранении динамической сборки с помощью Save метода. Чтобы создать исполняемый файл, необходимо вызвать метод SetEntryPoint, который определяет точку входа в сборку. Сборки сохраняются как библиотеки DLL по умолчанию, если SetEntryPoint метод не запрашивает создание консольного приложения или приложения под управлением Windows.
В следующем примере показано, как создать, сохранить и запустить сборку с помощью .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 объектов. Вы можете загрузить определенную динамическую сборку и вызвать методы в загруженной сборке. Например, чтобы убедиться, что модули ресурсов включены в возвращаемый список модулей GetModules, вызовите Assembly на загруженном объекте GetModules. Если динамическая сборка содержит несколько динамических модулей, имя файла манифеста сборки должно совпадать с именем модуля, указанным в качестве первого аргумента DefineDynamicModule метода.
Подписывание динамической сборки с помощью KeyPair не будет эффективным, пока сборка не сохранена на диске. Поэтому строгие имена не будут работать с временными динамическими сборками.
Динамические сборки могут ссылаться на типы, определенные в другой сборке. Временная динамическая сборка может безопасно ссылаться на типы, определенные в другой временной динамической сборке, сохраняемой динамической сборке или статической сборке. Однако среда CLR не позволяет сохраняемому динамическому модулю ссылаться на тип, определенный в временном динамическом модуле. Это связано с тем, что при загрузке сохраняемого динамического модуля после сохранения на диск среда выполнения не может разрешать ссылки на типы, определенные в временном динамическом модуле.
Ограничения на отправку в удаленные домены приложений
Для некоторых сценариев требуется создать динамическую сборку и выполнить ее в домене удаленного приложения. Отражение не позволяет динамической сборке создаваться непосредственно в удаленный домен приложения. Решение состоит в том, чтобы выпустить динамическую сборку в текущем домене приложения, сохранить динамическую сборку на диск, а затем загрузить динамическую сборку в домен удаленного приложения. Домены удаленного взаимодействия и приложений поддерживаются только в .NET Framework.