Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Троелсен Э. Язык программирования С# 2010 и п...docx
Скачиваний:
113
Добавлен:
21.09.2019
Размер:
6.92 Mб
Скачать

Общедоступные компоновочные блоки

Теперь, когда вы понимаете, как инсталлировать и конфигурировать приватные компоновочные блоки, мы с вами можем приступить к рассмотрению роли общедоступных компоновочных блоков. Подобно приватному компоновочному блоку, общедоступный компоновочный блок представляет собой набор типов и (возможно) ресурсов. Самой очевидной особенностью общедоступных компоновочных блоков, в отличие от приватных, является то, что одна и та же копия общедоступного компоновочного блока может использоваться разными приложениями.

Так, многие приложения в этой книге указывают ссылку на System.Windows.Forms.dll. Но если заглянуть в каталоги этих приложений, вы не обнаружите там приватные копии этого компоновочного блока .NET. Причина в том, что System.Windows.Forms.dll инсталлируется, как общедоступный компоновочный блок. Очевидно, что именно такой подход нужна использовать при создании библиотеки классов, используемой на уровне всей машины.

Общедоступный компоновочный блок не инсталлируется в каталог использующего его приложения. Общедоступные компоновочные блоки устанавливаются в GAC (Global Assembly Cache – глобальный кэш компоновочных блоков). Каталог GAC является подкаталогом с именем assembly в корневом каталоге Windows (например, C:\Windows\assembly), как показано на рис. 11.16.

Рис. 11.16. Глобальный кэш компоновочных блоков

Замечание. Выполняемые компоновочные блоки (*.exe) устанавливать в каталог GAC нельзя. Общедоступными компоновочными блоками могут быть только блоки, имеющие вид *.dll.

Строгая форма имени

Перед установкой компоновочного блока в GAC вы должны назначить компоновочному блоку строгое имя, которое уникальным образом идентифицирует издателя данного двоичного объекта .NET. При этом следует понимать, что "издателем" может быть и отдельный программист, и подразделение в рамках отдельной компании, и отдельная компания целиком.

В некотором смысле строгое имя является современным .NET-эквивалентом схемы GUID-идентификации COM. Если вы имеете опыт работы с COM, вспомните о том, что AppID (идентификатор приложения) – это GUID (Globally Unique IDentifter – глобальный уникальный идентификатор), характеризующий конкретное COM-приложение. В отличие от GUID-значений в COM (которые являются ничем иным, как 128-разрядными числами), строгие имена создаются на основе двух связанных криптографических ключей (называемых открытым ключом и секретным ключом). Поэтому строгие имена оказываются гораздо более стойкими в отношении искажений и должны быть ближе к уникальности, чем простые GUID-значения.

Формально строгое имя компонуется из набора связанных данных, в большинстве своем задаваемых следующими атрибутами уровня компоновочного блока.

• Понятное имя компоновочного блока (которое, напоминаем, является именем компоновочного блока без расширения файла)

• Номер версии компоновочного блока (назначаемый с помощью атрибута [AssemblyVersion])

• Значение открытого ключа (назначаемое с помощью атрибута [AssemblyKeyFile])

• Необязательное значение идентификатора культуры, используемого для локализации (назначаемое с помощью атрибута [AssemblyCulture])

• Встроенная цифровая подпись, создаваемая с помощью хеширования всего содержимого компоновочного блока с использованием значения секретного ключа

Чтобы создать строгое имя для компоновочного блока, вашим первым шагом должно быть генерирование пары ключей (открытого и секретного) с помощью утилиты sn.exe .NET Framework 2.0 SDK (что мы с вами сделаем чуть позже). Утилита sn.exe генерирует файл, обычно с расширением *.snk (Strong Name Key – ключ строгого имени), который содержит данные двух разных, но математически связанных ключей (это так называемые "открытый" и "секретный" ключи). Если компилятор C# получит информацию о месте нахождения файла *.snk, то во время компиляции значение открытого ключа будет записано в манифест создаваемого компоновочного блока с помощью лексемы .publickey.

Компилятор C# также сгенерирует хешированный код на основе всего содержимого компоновочного блока (CIL-кода, метаданных и т.д.). Вы должны знать из главы 3, что хешированный код представляет собой числовое значение, уникальным образом характеризующее вводимые данные. Так, при изменении любой части компоновочного блока (даже одного-единственного символа строкового литерала) .NET-компилятор генерирует уже другой хешированный код. Этот хешированный код комбинируется с данными секретного ключа из файла *. snk для получения цифровой подписи, встраиваемой в CLR-заголовок компоновочного блока. Процесс создания строго именованного компоновочного блока схематически показан на рис. 11.17.

Следует понимать, что данные секретного ключа нигде в манифесте представлены не будут – они используется только при создании цифровой подписи содержимого компоновочного блока (в совокупности с генерируемым хешированным кодом). Напомним, что основной целью применения криптографии на основе открытого и секретного ключей является гарантия того, что во "вселенной" .NET никакая пара компаний, подразделений или индивидуумов не получит одинаковых идентификаторов. Так или иначе, по завершении процесса создания строгого имени компоновочный блок можно будет установить в структуру GAC.

Рис. 11.17. В процессе компиляции на основе открытого и секретного ключей генерируется цифровая подпись, которая затем встраивается в компоновочный блок

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