Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка для КР по ООП.doc
Скачиваний:
8
Добавлен:
18.04.2019
Размер:
2.47 Mб
Скачать

Класс сборки в действии

Исследование свойств и областей применения класса Assembly начинаем с создания тестовой однофайловой сборки AssemblyForStart в рамках проекта Class Library.

Первая сборка Operators00.exe:

using System;

namespace Operators00

{

public class xPoint

{

float x, y;

xPoint()

{

x = 0.0F;

y = 0.0F;

}

public xPoint(float xKey, float yKey):this()

{

x = xKey;

y = yKey;

}

public static bool operator true(xPoint xp)

{

if (xp.x != 0.0F && xp.y != 0.0F) return true;

else return false;

}

public static bool operator false(xPoint xp)

{

if (xp.x == 0.0F || xp.y == 0.0F) return false;

else return true;

}

public static xPoint operator | (xPoint key1, xPoint key2)

{

if (key1) return key1;

if (key2) return key2;

return new xPoint();

}

public static xPoint operator & (xPoint key1, xPoint key2)

{

if (key1 && key2) return new xPoint(1.0F, 1.0F);

return new xPoint();

}

public void Hello()

{

Console.WriteLine(“Hello! Point {0},{1} is here!”,this.x,this.y);

}

}

class Class1

{

/// <summary>

/// The main entry Point for the application.

/// </summary>

[STAThread]

static void Main() // У точки входа пустой список параметров.

// Я пока не сумел ей передать через метод Invoke массива строк.

{

xPoint xp0 = new xPoint(1.0F, 1.0F);

xPoint xp1 = new xPoint(1.0F, 1.0F);

if (xp0 || xp1) Console.WriteLine(“xp0 || xp1 is true!”);

else Console.WriteLine(“xp0 || xp1 is false!”);

}

}

}

Вторая сборка AssemblyForStart.dll. В примере она так и не запускалась. Используется только для тестирования стандартных средств загрузки сборок-библиотек классов.

using System;

namespace AssemblyForStart

{

/// <summary>

/// Class1 : первая компонента сборки AssemblyForStart.

/// </summary>

public class Class1

{

public Class1()

{

Console.WriteLine(“This is constructor Class1()”);

}

public void fC1()

{

Console.WriteLine(“This is fC1()”);

}

}

}

А вот полигон AssemblyStarter.exe. В примере демонстрируется техника ПОЗДНЕГО СВЯЗЫВАНИЯ. Именно поэтому код, который выполняется после загрузки сборки не содержит в явном виде информации об используемых в приложении типах. Транслятор действует в строгом соответствии с синтаксисом языка C# и просто не поймёт пожелания “создать объект-представитель класса … который будет объявлен в сборке, которую предполагается загрузить в ходе выполнения приложения”.

using System;

using System.Reflection;

using System.IO;

namespace AssemblyStarter

{

/// <summary>

/// Приложение обеспечивает запуск сборки.

/// </summary>

class Class1

{

static void Main(string[] args)

{

// Сборка может быть вызвана непосредственно по имени

// (строковый литерал с дружественным именем сборки).

// Ничего особенного. Просто имя без всяких там расширений.

// Главная проблема заключается в том, сборки должны предварительно

// включаться в раздел References (Ссылки).

// Кроме того, информация о загружаемой сборке может быть представлена

// в виде объекта - представителя класса AssemblyName, ссылка на который

// также может быть передана в качестве аргумента методу Assembly.Load().

// Вот здесь как раз и происходит формирование этого самого объекта.

AssemblyName asmName = new AssemblyName();

asmName.Name = “AssemblyForStart”;

// Версию подсмотрели в манифесте сборки с помощью IlDasm.exe.

Version v = new Version(“1.0.1790.25124”);

// Можно было бы для пущей крутизны кода поле Version проинициализировать

// непосредственно (дело хозяйское):

// asmName.Version = new Version(«1:0:1790:25124»);

asmName.Version = v;

// Ссылка на объект-представитель класса Assembly.

//

Assembly asm = null;

try

{

// Загрузка сборки по «дружественному имени».

//asm = Assembly.Load(«AssemblyForStart»);

// Путь и полное имя при загрузки частной сборки не имеют значения.

// Соответствующие файлы должны располагаться непосредственно в каталоге приложения.

//asm = Assembly.Load

//(@”D:\Users\WORK\Cs\AssemblyTest\AssemblyForStart\bin\Debug\AssemblyForStart.dll”);

//asm = Assembly.Load(asmName);

// Если сборку организовать в виде исполняемого модуля и «запихнуть» в каталог

// вручную - загрузится и такая сборка.

asm = Assembly.Load(“Operators00”);

}

catch(FileNotFoundException e)

{

Console.WriteLine(“We have a problem:” + e.Message);

}

// Итак, решено. Загрузили сборку, содержащую объявление класса xPoint.

// Если сборка загрузилась - с ней надо что-то делать. Ясное дело,

// надо выполнять программный код сборки.

// Первый вариант выполнения. В сборке содержатся объявления двух классов:

// класса xPoint и класса Class1. Мы воспользуемся объявлением класса xPoint,

// построим соответствующий объект-представитель этого класса, после чего

// будем вызывать нестатические методы-члены этого класса.

// Всё происходит в режиме ПОЗДНЕГО связывания. Поэтому ни о каких ЯВНЫХ упоминаниях

// имён типов не может быть речи. Единственное явное упоминание - это упоминание

// имени метода.

object[] ps = {25,25};

Type[] types = asm.GetTypes();

// Здесь используется класс Activator!

object obj = Activator.CreateInstance(types[0],ps);

MethodInfo mi = types[0].GetMethod(“Hello”);

mi.Invoke(obj,null);

// Второй вариант выполнения. Воспользуемся тем обстоятельством, что загружаемая

// сборка не является библиотекой классов, а является обычной выполнимой сборкой

// с явным образом обозначенной точкой входа - СТАТИЧЕСКОЙ функцией Main(), которая

// является членом класса Class1.

mi = asm.EntryPoint;

// Вот всё получилось! Единственное, что я не сделал, так это не смог передать

// в точку входа загруженной сборки массива строк-параметров

// (смотреть на точку входа данной сборки).

// Ну не удалось. Потому и в сборке Operators точку сборки объявил без параметров.

mi.Invoke(null,null);

}

}

}

Собрали, запустили. Получилось. Стало быть, ВСЁ ХОРОШО.

В ходе выполнения приложения класс Assembly позволяет:

  • получать информацию о самой сборке,

  • обращаться к членам класса, входящим в сборку,

загружать другие сборки.