ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание
Шрифт:
Если выполнить это обновленное приложение теперь, методы соответствующего типа будут описаны более подробно. Для примера на рис. 12.3 показаны метаданные методов для типа System.Globalization.GregorianCalendar.
Рис. 12.3. Подробное описание методов System.Globalization.GregorianCalendar
Весьма увлекательно, не так ли? Ясно, что пространство имен System.Reflection и класс System.Type позволяют отображать многие другие
Но и в нынешнем своем виде ваш обозреватель объектов уже кое-что умеет. Главным его ограничением, конечно же, является то, что у вас нет никакой возможности отображать объекты, размещенные вне данного компоновочного блока (MyTypeViewer) или всегда доступного mscorlib.dll. В связи с этим остается открытым вопрос: "Как строить приложения, которые могут загружать (и отображать) компоновочные блоки, о которых нет информации во время компиляции?"
Исходный код. Проект MyTypeViewer размещен в подкаталоге, соответствующем главе 15.
Динамически загружаемые компоновочные блоки
Из предыдущей главы вы узнали о том, как среда CLR использует информацию манифеста компоновочного блока при зондировании компоновочных блоков по внешним ссылкам. Все это, конечно, хорошо, но во многих случаях бывает необходимо "на лету" загрузить компоновочный блок программными средствами, а записей о соответствующем компоновочном блоке в манифесте нет. Формально загрузка внешних компоновочных блоков по запросу называется динамической загрузкой.
В рамках System.Reflection определяется класс, имя которого Assembly. Используя этот тип, можно динамически загрузить любой компоновочный блок, а также выяснить его свойства. Используя тип Assembly, можно динамически загружать приватные и общедоступные компоновочные блоки, размещенные в любом месте системы. Класс Assembly предлагает методы (в частности, Load и LoadFrom), позволяющие программными средствами получать информацию, аналогичную той, которая содержится в файле *.config клиента.
Для примера использования динамической загрузки создайте новое консольное приложение с именем ExternalAssemblyReflector. Вашей задачей является построение метода Main, запрашивающего понятное имя компоновочного блока для динамической загрузки. Ссылка Assembly будет передана вспомогательному методу DisplayTypes, который просто напечатает имена всех, классов, интерфейсов, структур, перечней и делегатов соответствующего компоновочного блока. Необходимый программный код выглядит довольно просто.
Обратите внимание на то, что статическому методу Assembly.Load передается только понятное имя компоновочного блока, который вы хотите загрузить в память. Поэтому, чтобы получить отображение CarLibrary.dll с помощью этой программы, перед ее выполнением нужно скопировать двоичный файл CarLibrary.dll в каталог \Bin\Debug приложения ExternalAssemblyReflector. После этого вывод программы будет аналогичен показанному на рис. 12.4.
Рис. 12.4. Отображение внешнего компоновочного блока CarLibrary
Замечание. Чтобы приложение ExternalAssemblyReflector было более гибким, следует загружать внешний компоновочный блок с помощью Assembsly.LoadFrom, а не с помощью Assembly.Load. Тогда вы сможете указать для соответствующего компоновочного блока абсолютный путь (например, C:\MyApp\MyAsm.dll).
Исходный код. Проект ExternalAssemblyReflector размещен в подкаталоге, соответствующем главе 12.
Отображение общедоступных компоновочных блоков
Как вы можете догадываться, метод Assembly.Load является перегруженным. Один из вариантов метода Assembly.Load позволяет указать значение параметра culture (для локализованных компоновочных блоков), а также номер версии и значение открытого ключа (для общедоступных компоновочных блоков).
Весь набор элементов, идентифицирующих компоновочный блок, называют дисплейным (или отображаемым) именем. По своему формату дисплейное имя представляет собой строку пар имен и значений, разделенных запятыми, которая начинается с понятного имени компоновочного блока и продолжается необязательными определениями (они могут указываться в любом порядке). Вот как выглядит соответствующий шаблон (в скобках указаны необязательные элементы).