Исследование свойств и областей применения класса 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»);
// Путь и полное имя при загрузки частной сборки не имеют значения.
// Соответствующие файлы должны располагаться непосредственно в каталоге приложения.