Генерирование динамического компоновочного блока

Генерирование динамического компоновочного блока

Чтобы проиллюстрировать процесс определения компоновочного блока .NET в среде выполнения, давайте создадим одномодульный динамический компоновочный блок с именем MyAssembly.dll. В этом модуле будет содержаться класс HelloWorld. Тип HelloWorld поддерживает конструктор, используемый по умолчанию, и пользовательский конструктор для присваивания значения приватной переменной (theMessage) типа string. Кроме того, HelloWorld предлагает открытый метод экземпляра с именем SayHello(), который выводит приветствие в стандартный поток ввода-вывода, а также еще один метод экземпляра, GetMsg(), который возвращает внутреннюю приватную строку. В результате вы должны программно сгенерировать следующий тип класса.

// Этот класс будет создан в среде выполнения

// с помощью System.Reflection.Emit.

public class HelloWorld {

 private string theMessage;

 HelloWorld() {}

 HelloWorld(string s) { theMessage = s; }

 public string GetMsg() { return theMessage; }

 public void SayHello() {

  System.Console.WriteLine("Привет от класса HelloWorld!");

 }

}

Предположим, вы cоздали новый проект консольного приложения в Visual Studio 2005, назвав его DynAsmBuilder. Переименуйте исходный класс в MyAsmBuilder и определите статический метод с именем CreateMyAsm(). Этот единственный метод будет ответственен за следующее:

• определение характеристик динамического компоновочного блока (имя, версия и т.д.);

• реализацию тина HelloClass;

• запись компоновочного блока, сгенерированного в памяти, в физический файл.

Также отметим, что метод CreateMyAsm() использует в качестве единственного параметра тип System.AppDomain, который будет использоваться для получения доступа к типу AssemblyBuilder, связанному с текущим доменом приложения (см. главу 13, где обсуждаются домены приложений .NET). Вот полный программный код, с последующим анализом.

// Вызывающая сторона посылает тип AppDomain.

public static void CreateMyAsm(AppDomain currAppDomain) {

 // Установка общих характеристик компоновочного блока.

 AssemblyName assemblyName = new AssemblyName();

 assemblyName.Name = "MyAssembly";

 assemblyName.Version = new Version("1.0.0.0");

 // Создание нового компоновочного блока

 // в рамках текущего домена приложения.

 AssemblyBuilder assembly = curAppDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);

 // Поскольку создается одномодульный компоновочный блок,

 // имя модуля будет совпадать с именем компоновочного блока.

 ModuleBuilder module = assembly.DefineDynamicModule("MyAssembly", "MyAssemblу.dll");

 // Определение открытого класса с именем "HelloWorld".

 TypeBuilder helloWorldClass = module.DefineType("MyAssembly.HelloWorld", TypeAttributes.Public);

 // Определение приватной переменной String с именем "theMessage".

 FieldBuilder msgField = helloWorldClass.DefineField("theMessage", Type.GetType("System.String"), FieldAttributes.Private);

 // Создание пользовательского конструктора.

 Type[] constructorArgs = new Type[1];

 constructorArgs[0] = typeof(string);

 ConstructorBuilder constructor = helloWorldClass.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorArgs);

 ILGenerator constructorIL = constructor.GetILGenerator();

 constructorIL.Emit(OpCodes.Ldarg_0);

 Type objectClass = typeof(object);

 ConstructorInfo superConstructor = objectClass.GetConstructor(new Type[0]);

 constructorIL.Emit(OpCodes.Call, superConstructor);

 constructorIL.Emit(Opcodes.Ldarg_0);

 constructorIL.Emit(Opcodes.Ldarg_1);

 constructorIL.Emit(OpCodes.Stfld, msgField);

 constructorIL.Emit(OpCodes.Ret);

 // Создание конструктора, заданного по умолчанию.

 helloWorldClass.DefineDefaultConstructor(MethodAttributes.Public);

 // Теперь создание метода GetMsg().

 MethodBuilder getMsgMethod = helloWorldClass.DefineMethod("GetMsg", MethodAttributes.Public, typeof(string), null);

 ILGenerator methodIL = getMsgMethod.GetILGenerator();

 methodIL.Emit(OpCodes.Ldarg_0);

 methodIL.Emit(OpCodes.Ldfld, msgField);

 methodIL.Emit(Opcodes.Ret);

 // Создание метода SayHello.

 MethodBuilder sayHiMethod = helloWorldClass.DefineMethod("SayHello", MethodAttributes.Public, null, null);

 methodIL = sayHiMethod.GetILGenerator();

 methodIL.EmitWriteLine("Привет от класса HelloWorld!");

 methodIL.Emit(Opcodes.Ret);

 // Генерирование класса HelloWorld.

 helloWorldClass.CreateType();

 // (Необязательно.) Сохранение компоновочного блока в файл.

 assembly.Save("MyAssembly.dll");

}

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Роль манифеста компоновочного блока

Из книги Язык программирования С# 2005 и платформа .NET 2.0. [3-е издание] автора Троелсен Эндрю

Роль манифеста компоновочного блока Наконец вспомним, что компоновочный блок .NET содержит также метаданные, описывающие сам компоновочный блок (эти метаданные называются манифест). Среди всего прочего, в манифесте документируются все внешние компоновочные блоки,


Формат компоновочного блока  .NET

Из книги автора

Формат компоновочного блока  .NET Теперь, когда вы знаете о некоторых преимуществах, обеспечиваемых компоновочными блоками .NET, давайте немного сместим акценты и попытаемся понять то, как устроены компоновочные блоки. С точки зрения внутренней структуры, компоновочный


Необязательные ресурсы компоновочного блока

Из книги автора

Необязательные ресурсы компоновочного блока Наконец, компоновочный блок .NET может содержать любой набор встроенных ресурсов, таких как, например, пиктограммы приложении, графические файлы, звуковые фрагменты или таблицы строк. Платформа .NET обеспечивает поддержку


Фиксация версии общедоступного компоновочного блока

Из книги автора

Фиксация версии общедоступного компоновочного блока Чтобы показать, как осуществляется динамическая привязка к конкретной версии общедоступного компоновочного блока, откроите программу Проводник Windows в скопируйте текущую версию CarLibrary (1.0.0.0) в другой подкаталог (здесь


Создание общедоступного компоновочного блока версии 2.0.0.0

Из книги автора

Создание общедоступного компоновочного блока версии 2.0.0.0 Теперь обновите свой проект CarLibrary, добавив в него определение нового перечня MusicMedia, определяющего четыре возможных музыкальных устройства.// Содержит информацию об источнике музыки.public enum MusicMedia


Представление метаданных компоновочного блока

Из книги автора

Представление метаданных компоновочного блока Окно метаданных ildasm.exe позволяет также просмотреть метаданные самого компоновочного блока, для обозначения которых используется метка Assembly. Следующий фрагмент листинга показывает, что информация, представленная в таблице


Определение текущего компоновочного блока

Из книги автора

Определение текущего компоновочного блока Следующей задачей является определение компоновочного блока, который вы хотите построить. Это делается с помощью директивы .assembly. В простейшем случае компоновочный блок можно определить с помощью простого указания понятного


Создание компоновочного блока .NET в CIL

Из книги автора

Создание компоновочного блока .NET в CIL Теперь, освоив синтаксис и семантику CIL, вы можете закрепить свои знания на практике, построив приложение .NET с использованием только CIL и текстового редактора. Ваше приложение будет состоять из приватного одномодульного *.dll,


Генерирование компоновочного блока и набора модулей

Из книги автора

Генерирование компоновочного блока и набора модулей Метод начинается с указания минимального набора характеристик компоновочного блока, для чего используются типы AssemblyName и Version (определенные в пространстве имен System.Reflection). Затем с помощью метода уровня экземпляра


Создание общего компоновочного блока

Из книги автора

Создание общего компоновочного блока Сначала создадим общий компоновочный блок, SimpleRemotingAsm.dll, на который будут ссылаться как сервер, так и клиент. В SimpleRemotingAsm.dll определяется единственный MBR-тип с именем RemoteMessageObject, который поддерживает два открытых члена. Метод DisplayMessage()


Создание компоновочного блока сервера

Из книги автора

Создание компоновочного блока сервера Напомним, что компоновочные блоки сервера обслуживают, в частности, и общие компоновочные блоки, содержащие объекты удаленного доступа. Создайте консольную программу с именем SimpleRemoteObjectServer. Роль серверного компоновочного блока


Создание компоновочного блока клиента

Из книги автора

Создание компоновочного блока клиента Теперь, когда у вас есть приемник, который будет обслуживать объекты уда-ленного доступа, остается создать компоновочный блок, который запросит доступ к соответствующим возможностям. Здесь снова создайте простое консольное


Создание общего компоновочного блока

Из книги автора

Создание общего компоновочного блока В ходе нашего обсуждения процесса сериализации объектов в главе 17 мы создали тип JamesBondCar (в дополнение к связанным классам Radio и Car). Библиотека программного кода CarGeneralAsm.dll будет использовать эти типы, поэтому сначала выберите Projects?Add


Создание компоновочного блока сервера

Из книги автора

Создание компоновочного блока сервера Компоновочный блок сервера (CarProviderServer.exe) в рамках метода Main() содержит следующую программную логику.using System;using System.Runtime.Remoting;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting.Channels.Http;using CarGeneralAsm;namespace CarProviderServer { class CarServer {  static void Main(string[] args) {  


Создание компоновочного блока клиента

Из книги автора

Создание компоновочного блока клиента Наконец, рассмотрим приложение клиента, которое будет использовать MBR-тип CarProvider для получения отдельных типов JamesBondCars и типа List‹›. После получения типа от CarProvider вы посылаете его вспомогательной функции UseCar() для обработки.using