Динамически загружаемые компоновочные блоки

We use cookies. Read the Privacy and Cookie Policy

Динамически загружаемые компоновочные блоки

Из предыдущей главы вы узнали о том, как среда CLR использует информацию манифеста компоновочного блока при зондировании компоновочных блоков по внешним ссылкам. Все это, конечно, хорошо, но во многих случаях бывает необходимо "на лету" загрузить компоновочный блок программными средствами, а записей о соответствующем компоновочном блоке в манифесте нет. Формально загрузка внешних компоновочных блоков по запросу называется динамической загрузкой.

В рамках System.Reflection определяется класс, имя которого Assembly. Используя этот тип, можно динамически загрузить любой компоновочный блок, а также выяснить его свойства. Используя тип Assembly, можно динамически загружать приватные и общедоступные компоновочные блоки, размещенные в любом месте системы. Класс Assembly предлагает методы (в частности, Load() и LoadFrom()), позволяющие программными средствами получать информацию, аналогичную той, которая содержится в файле *.config клиента.

Для примера использования динамической загрузки создайте новое консольное приложение с именем ExternalAssemblyReflector. Вашей задачей является построение метода Main(), запрашивающего понятное имя компоновочного блока для динамической загрузки. Ссылка Assembly будет передана вспомогательному методу DisplayTypes(), который просто напечатает имена всех, классов, интерфейсов, структур, перечней и делегатов соответствующего компоновочного блока. Необходимый программный код выглядит довольно просто.

using System;

using System.Reflection;

using System.IO; // Для определения FileNotFoundException.

namespace ExternalAssemblyReflector {

 class Program {

  static void DisplayTypesInAsm(Assembly asm) {

   Console.WriteLine(" *** Типы компоновочного блока ***");

   Console.WriteLine("-› {0}", asm.FullName);

   Type[] types = asm.GetTypes();

   foreach (Type t in types) Console.WriteLine("Тип: {0}", t);

   Console.WriteLine(");

  }

  static void Main(string[] args) {

   Console.WriteLine("*** Обзор внешних компоновочных блоков ***");

   string asmName = ";

   bool userIsDone = false;

   Assembly asm = null;

   do {

    Console.WriteLine(" Введите имя компоновочного блока");

    Console.Write("или нажмите Q для выхода из приложения:");

    // Получение имени компоновочного блока.

    asmName = Console.ReadLine();

    // Желает ли пользователь завершить работу приложения?

    if (asmName.ToUpper() == "Q") {

     userIsDone = true;

     break;

    }

    // Попытка загрузить компоновочный блок.

    try {

     asm = Assembly.Load(asmName);

     DisplayTypesInAsm(asm);

    } catch {

     Console.WriteLine("Извините, компоновочный блок не найден.");

    }

   } while (userIsDone);

  }

 }

}

Обратите внимание на то, что статическому методу Assembly.Load() передается только понятное имя компоновочного блока, который вы хотите загрузить в память. Поэтому, чтобы получить отображение CarLibrary.dll с помощью этой программы, перед ее выполнением нужно скопировать двоичный файл CarLibrary.dll в каталог BinDebug приложения ExternalAssemblyReflector. После этого вывод программы будет аналогичен показанному на рис. 12.4.

Рис. 12.4. Отображение внешнего компоновочного блока CarLibrary

Замечание. Чтобы приложение ExternalAssemblyReflector было более гибким, следует загружать внешний компоновочный блок с помощью Assembsly.LoadFrom(), а не с помощью Assembly.Load(). Тогда вы сможете указать для соответствующего компоновочного блока абсолютный путь (например, C:MyAppMyAsm.dll).

Исходный код. Проект ExternalAssemblyReflector размещен в подкаталоге, соответствующем главе 12.