Внутри модуля находится класс HelloWorld
theMessage) типа string. Вдобавок в классе HelloWorld имеется открытый метод экземпляра под названием SayНеllo(), который выводит приветственное сообщение в стандартный поток ввода-вывода, и еще один метод экземпляра по имени 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("Hello from the HelloWorld class!");
}
}
Создайте новый проект консольного приложения по имени MyAsmBuilder
System.Reflection.Emit. Импортируйте в него пространства имен System.Reflection и System.Reflection.Emit. Определите в классе Program статический метод по имени CreateMyAsm(). Этот единственный метод будет отвечать за решение следующих задач:• определение характеристик динамической сборки (имя, версия и т.п.);
• реализация типа HelloClass
• возвращение вызывающему методу объекта AssemblyBuilder
Ниже приведен полный код, а затем его анализ:
static AssemblyBuilder CreateMyAsm()
{
// Установить общие характеристики сборки.
AssemblyName assemblyName = new AssemblyName
{
Name = "MyAssembly",
Version = new Version("1.0.0.0")
};
// Создать новую сборку.
var builder = AssemblyBuilder.DefineDynamicAssembly(
assemblyName,AssemblyBuilderAccess.Run);
// Определить имя модуля.
ModuleBuilder module =
builder.DefineDynamicModule("MyAssembly");
// Определить открытый класс по имени HelloWorld.
TypeBuilder helloWorldClass =
module.DefineType("MyAssembly.HelloWorld",
TypeAttributes.Public);
// Определить закрытую переменную-член типа String по имени theMessage.
FieldBuilder msgField = helloWorldClass.DefineField(
"theMessage",
Type.GetType("System.String"),
attributes: 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().