Общие сборки и GAC

Общие сборки .NET хранятся в глобальном кэше сборок (GAC). Наличие глобального кэша экономит дисковое пространство и память, поскольку на стадии выполнения программы на диске или в памяти достаточно хранить лишь один экземпляр сборки. Конечно, при совместном использовании сборок возникают некоторые проблемы, присущие старому механизму совместного использования DLL на базе реестра. К счастью, средства контроля версии .NET позволяют хранить в GAC разные версии одной сборки, поэтому каждое приложение может использовать нужную версию. Постарайтесь как можно реже использовать глобальный кэш сборок и ограничиться следующими ситуациями:

  • если использование сборки в разных приложениях вызвано абсолютной необходимостью, но по соображениям экономии места хранение нескольких локальных копий нежелательно;
  • если сборка требует особого уровня защиты (удаление сборок из GAC разрешено только администратору).
  • Список сборок, находящихся в GAC, выводится утилитой gacutil.exe из каталога \bin .NET SDK. Команда имеет следующий синтаксис: gacutil.exe -1

    Ниже приведено начало списка для одного из наших компьютеров. Полный список имеет внушительные размеры; даже на этой ранней стадии существования .NET он занимает около трех страниц:

    Microsoft (R).NET Global Assembly Cache Utility.Version 1.0.2914.16

    Copyright (C)Microsoft Corp,1998-2001,All rights reserved.

    The Global Assembly Cache contains the following assemblies:

    Accessibili ty.Version=1.0.2411.0,Culture=neutral,

    PublicKeyToken-b03f5f7flld50a3a,Custom=null

    ADODB,Version=2. 7.0.0.Culture-neutral,

    PublicKeyToken-b03f5f7fIld50a3a, Custom=null

    CRVsPackageLib.Version=1.0.0.0.Culture-neutral,

    PublicKeyToken=4f3430cff154c24c,Custom=nul1

    Crystal Deci si ons.Crystal

    Reports.Engine.Version=9.1.0.0.Culture-neutral,

    PublicKeyToken=4f3430cff154c24c,Custom=nul 1

    Для общих сборок контроль версии играет гораздо более важную роль, чем для закрытых сборок, поэтому в списке указаны номера версий каждой сборки. Последнее из Четырех чисел в номере версии определяет номер ежедневного построения, изменение которого считается непринципиальным. Далее следует номер ревизии, изменение которого тоже считается непринципиальным. Изменения следующих двух чисел (дополнительного и основного номеров) принципиальны. Это означает, что если программа запрашивает сборку версии 2.0.0.0, а в GAC находится только версия 2.5.0.0, программа не будет работать, если не внести специальные изменения в конфигурационный файл. С другой стороны, версия 2.0.0.37 считается совместимой с версией 2.0.0.0 и успешно загружается.

    Все сборки, включаемые в GAC, должны обладать сильными именами. Это связано с тем, что в GAC могут храниться две разные версии одной сборки, которые различаются по сильному имени.

     

    Включение и удаление сборок из GAC

    Чтобы общая сборка автоматически включалась в GAC в процессе установки, проще всего воспользоваться программой установки с поддержкой GAC — например, последней версией пакета Microsoft Installer (MSI). Описание этой программы выходит за рамки книги, но мы укажем, что эту программу можно бесплатно загрузить с сайта MSDN (align="left">На стадии разработки вместо программы установки обычно используется утилита

    gacutil.exe. Синтаксис командной строки:

    gacutil -1 <имя_сборки>

    Сборка с заданным именем помещается в GAC.

     

    Сильные имена и совместное использование сборок

    Сильные имена, как и GUID, должны быть уникальными в пространстве и времени. В отличие от GUID, которые теоретически могут быть похищены, сильные имена защищены от несанкционированного использования при помощи механизма шифрования с открытым ключом [ При условии надежного хранения закрытого ключа. ]. Конкретные схемы шифрования бывают очень сложными, однако в целом шифрование с открытым ключом построено на довольно простой идее — в некоторых ситуациях вернуться от конечного результата к исходным данным бывает очень, очень сложно. Например, вы можете легко перемножить два целых числа и получить результат, но узнать исходные множители по произведению невозможно — для этого нужно знать хотя бы один из них [ Этот принцип заложен в основу RSA, распространенного алгоритма шифрования с открытым ключом. ].

    Внутренняя реализация выглядит следующим образом: на основании всей информа-ции, содержащейся в сборке, .NET вычисляет хэш-код и применяет к нему закрытый ключ. Результатом является зашифрованный хэш-код. Поскольку схема шифрования должна обеспечивать возможность восстановления зашифрованных данных, зашифрованный хэш-код расшифровывается при помощи открытого ключа, при этом получается исходный хэш-код. На последнем шаге хэш-код заново вычисляется на основании данных, содержащихся в манифесте, и два числа сравниваются. Если хэш-коды не совпадают, значит, сборка была модифицирована, и .NET отказывается загружать ее.

    Во всех схемах с открытым ключом используется пара ключей: открытый и закрытый. Открытый ключ (public key) может свободно распространяться, поскольку без знания закрытого ключа зашифрованное сообщение невозможно восстановить за сколько-нибудь приемлемый промежуток времени. Применение закрытого ключа к данным манифеста позволяет сертифицировать их. Другие пользователи при помощи открытого ключа убеждаются в том, что сборка поступила именно от вас, а не из постороннего источника. А в некоторых случаях (например, при использовании Verisign) они даже могут убедиться в том, что открытый ключ принадлежит именно вам, а не кому-то другому (шифрование с открытым ключом защищает целостность данных, но для проверки открытого ключа необходимы услуги третьей стороны).