Чтение онлайн

ЖАНРЫ

ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание

Троелсен Эндрю

Шрифт:

Name (,Culture = код_языка) (,Version = _главный_номер.дополнительный_номер.номер_компоновки.номep_вapиaнтa) (,PublicKeyToken= код_открытого_ключа)

Значение PublicKeyToken = null в строке, определяющей дисплейное имя, указывает на то, что при связывании проверка строгого имени не требуется и его наличие у компоновочного блока не обязательно. Значений Culture = "" сообщает о необходимости использований значения кода локализации, принятого на машине по умолчанию, например:

// Загрузка CarLibrary версии 1.0.982.23972 с кодом локализации,

//
используемым по умолчанию.

Assembly a = Assembly.Load(@"CarLibrary,Version=1.0.982.23972,PublicKeyToken=null,Culture=''");

Пространство имен System.Reflection предлагает также тип AssemblyName, который позволяет представить указанную выше информационную строку в объектной переменной. Обычно этот класс используется вместе с System.Version, являющимся объектным контейнером для номера версии компоновочного блока. Создав дисплейное имя, вы можете передать его перегруженному методу Assembly.Load.

// Использование AssemblyName для определения дисплейного имени.

AssemblyName asmName;

asmName = new AssemblyName;

asmName.Name = "CarLibrary";

Version v = new Version("1.0.982.23972");

asmName.Version = v;

Assembly a = Assembly.Load(asmName);

Чтобы загрузить общедоступный компоновочный блок из GAC, параметр Assembly.Load должен указать значение publickeytoken. Предположим, на-пример, что вы хотите загрузить компоновочный блок System.Windows.Forms.dll версии 2.0.0.0, предлагаемый библиотеками базовых классов .NET. Поскольку число типов в этом компоновочном блоке очень велико, следующее приложение выводит имена только первых 20 типов.

using System;

using System.Reflection;

using System.IO;

namespace SharedAsmReflector {

public class SharedAsmReflector {

private static void DisplayInfo(Assembly a) {

Console.WriteLine("***** Информация о компоновочном блоке *****");

Console.WriteLine("Загружен из GAC? {0}", a.GlobalAssemblyCache);

Console.WriteLine("Имя: {0}", a.GetName.Name);

Console.WriteLine("Версия: {0}", a.GetName.Version);

Console.WriteLine("Культура: {0}", a.GetName.CultureInfo.DisplayName);

Type[] types = a.GetTypes;

for (int i = 0; i ‹ 20; i++) Console.WriteLine("Тип: {0}", types[i]);

}

}

static void Main(string[] args) {

Console.WriteLine("***** Отображение общедоступных КБ *****\n");

// Загрузка System.Windows.Forms.dll из GAC.

string displayName = null;

displayName = "System.Windows.Forms," +

"Version=2.0.0.0," +

"PublicKeyToken=b77а5c561934e089" +

@"Culture=''";

Assembly asm = Assembly.Load(displayName);

DisplayInfo(asm);

Console.ReadLine;

}

 }

}

Исходный

код.
Проект SharedAsmReflector размещен в подкаталоге, соответствующем главе 12.

Чудесно! К этому моменту нашего обсуждения вы должны понять, как использовать некоторые базовые элементы из пространства имен System.Reflection для чтения метаданных компоновочного блока во время выполнения. Здесь я готов признать, что, несмотря на "фактор красоты" предлагаемого подхода, вам по роду своей деятельности вряд ли придется строить пользовательские навигаторы объектов. Но не следует забывать о том, что сервисы отображения являются основой целого ряда других, очень широко используемых подходов в программировании, включая и динамическое связывание.

Динамическое связывание

Упрощенно говоря, динамическое связывание, или динамическая привязка, – это подход, с помощью которого можно создавать экземпляры заданного типа и вызывать их члены в среде выполнения и условиях, когда во время компиляции о типе еще ничего не известно. При построении приложения, использующего динамическое связывание в отношении некоторого типа из внешнего компоновочного блока нет смысла устанавливать ссылку на такой компоновочный блок. Поэтому манифест вызывающей стороны и не содержит прямой ссылки.

На данном этапе обсуждения значение динамического связывания может казаться вам непонятным. Если вы имеете возможность использовать "статическую привязку" к типу (например, установить ссылку на компоновочный блок и поместить тип в память, используя ключевое слово C# new), то в этом случае так и нужно сделать. Статическое связывание позволяет обнаружить ошибки уже во время компиляции, а не во время выполнения программы. Однако динамическое связывание оказывается очень важным для построения приложений, обладающих более гибкими возможностями расширения.

Класс System.Activator

Класс System.Activator обеспечивает возможность реализации процесса динамической привязки в .NET. Кроме методов, унаследованных от System.Object, сам класс Activator определяет очень небольшое множество членов, многие из которых относятся к средствам удаленного взаимодействия .NET (cм. главу 18). Для нашего примера нам понадобится только метод Activator.CreateInstance, который используется для создания экземпляра типа в рамках динамической привязки.

Этот метод имеет множество перегруженных вариаций, что обеспечивает ему исключительную гибкость. Самая простая вариация члена CreateInstance должна получить на вход объект Туре, описывающий элемент, который вы хотите динамически разместить. Создайте новое приложение с именем LateBinding и модифицируйте его метод Main так, как показано ниже (не забудьте поместить копию CarLibrary.dll в каталог \Bin\Debug проекта).

// Динамическое создание типа.

public class Program {

Поделиться с друзьями: