Первым может возникнуть вопрос: чем отличаются статические сборки от динамических? По определению
Что касается
System.Reflection.Emit, которое делает возможным построение сборки и ее модулей, определений типов и логики реализации на языке CIL во время выполнения. Затем сборку, расположенную в памяти, можно сохранить на диск, получив в результате новую статическую сборку. Ясно, что процесс создания динамических сборок с помощью пространства имен System.Reflection.Emit требует понимания природы кодов операций CIL.Несмотря на то что создание динамических сборок является сложной (и редкой) задачей программирования, оно может быть удобным в разнообразных обстоятельствах. Ниже перечислены примеры.
• Вы строите инструмент программирования .NET Core, который должен быть способным генерировать сборки по требованию на основе пользовательского ввода.
• Вы создаете приложение, которое нуждается в генерации посредников для удаленных типов на лету, основываясь на полученных метаданных.
• Вам необходима возможность загрузки статической сборки и динамической вставки в двоичный образ новых типов.
Давайте посмотрим, какие типы доступны в пространстве имен System.Reflection.Emit
Исследование пространства имен System.Reflection.Emit
Создание динамической сборки требует некоторых знаний кодов операций CIL, но типы из пространства имен System.Reflection.Emit
TypeBuilder. Аналогично, если нужно определить новый конструктор уровня экземпляра, то не придется задавать лексему specialname, rtspecialname или .ctor; взамен можно использовать класс ConstructorBuilder. Основные члены пространства имен System.Reflection.Emit описаны в табл. 19.7.В целом типы из пространства имен System.Reflection.Emit
ILGenerator заслуживает специального внимания.Роль типа System.Reflection.Emit.ILGenerator
Роль типа ILGenerator
ILGenerator напрямую невозможно, т.к. этот тип не имеет открытых конструкторов. Взамен объекты ILGenerator должны получаться путем вызова специфических методов типов, относящихся к построителям (вроде MethodBuilder и ConstructorBuilder).Вот пример:
// Получить объект ILGenerator из объекта ConstructorBuilder
// по имени myCtorBuilder.
ConstructorBuilder myCtorBuilder = /* */;
ILGenerator myCILGen = myCtorBuilder.GetILGenerator();
Имея объект ILGenerator
ILGenerator кратко описаны в табл. 19.8.Основным методом класса ILGenerator
Emit(), который работает в сочетании с типом System.Reflection.Emit.Opcodes. Как упоминалось ранее в главе, данный тип открывает доступ к множеству полей только для чтения, которые отображаются на низкоуровневые коды операций CIL. Полный набор этих членов документирован в онлайновой справочной системе, и далее в главе вы неоднократно встретите примеры их использования.Выпуск динамической сборки
Чтобы проиллюстрировать процесс определения сборки .NET Core во время выполнения, давайте рассмотрим процесс создания однофайловой динамической сборки по имени MyAssembly.dll