Обнаружение сборок в среде выполнения

Примечание.

Эта статья относится к .NET Framework. Он не применяется к более новым реализациям .NET, включая .NET 6 и более поздние версии.

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

При попытке найти сборку и разрешить ссылку на нее среда CLR выполняет ряд действий. Каждый этап подробно описывается в приведенных ниже разделах. Термин "проверка" часто используется при описании того, как среда выполнения ищет сборки. Под ним понимается набор эвристических правил, используемых для обнаружения сборки на основе ее имени и языка и региональных параметров.

Примечание.

Сведения о привязке можно просмотреть в файле журнала с помощью средства просмотра журнала привязок сборки (Fuslogvw.exe), которое включено в Windows SDK.

Инициирование привязки

Процесс обнаружения и привязки к сборке начинается, когда среда выполнения пытается разрешить ссылку на другую сборку. Эта ссылка может быть статической или динамической. Компилятор записывает статические ссылки в метаданные манифеста сборки во время сборки. Динамические ссылки создаются в режиме реального времени в результате вызова различных методов, таких как Assembly.Load.

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

Динамическую ссылку на сборку также можно создать, предоставив вызывающему методу только часть сведений о сборке, например только ее имя. В этом случае сборка ищется только в каталоге приложения. Другие проверки не производятся. Создать частичную ссылку можно с помощью различных методов загрузки сборок, таких как Assembly.Load или AppDomain.Load.

Наконец, вы можете создать динамическую ссылку с помощью такого метода, как Assembly.Load и предоставить только частичную информацию; затем вы квалифицируйте ссылку с помощью <элемента qualifyAssembly> в файле конфигурации приложения. Этот элемент позволяет предоставлять полные данные ссылки (имя, версию, язык и региональные параметры и, при наличии, токен открытого ключа) в файле конфигурации приложения, а не в коде. Такой подход можно использовать, если требуется определить полную ссылку на сборку вне каталога приложения или сослаться на сборку в глобальном кэше сборок, используя преимущества определения полной ссылки в файле конфигурации, а не в коде.

Примечание.

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

Для разрешения ссылки на сборку среда выполнения выполняет указанные ниже действия.

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

  2. Проверяет, выполнялась ли привязка к имени сборки прежде , и если да, использует ранее загруженную сборку. Если предыдущий запрос загрузки сборки закончился неудачей, запрос немедленно прерывается без попытки загрузить сборку.

    Примечание.

    Кэширование сбоев привязки сборки новое в платформа .NET Framework версии 2.0.

  3. Проверяет глобальный кэш сборок. Если в нем удается найти сборку, среда выполнения использует ее.

  4. Проверяет наличие сборки , выполняя указанные ниже действия.

    1. Если конфигурация и политика издателя не влияют на исходную ссылку и запрос привязки создан с помощью метода Assembly.LoadFrom , среда выполнения пытается найти косвенные упоминания о расположении сборки.

    2. Если база кода находится в файлах конфигурации, среда выполнения проверяет только это расположение. Если происходит сбой проверки, среда выполнения определяет, что запрос привязки не выполнен, и другие проверки не производятся.

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

      Примечание.

      Если сборки не являются сборками со строгими именами, для них не проводятся ни проверка версии, ни поиск в глобальном кэше сборок.

Шаг 1. Проверка файлов конфигурации

Поведение привязки сборок можно настроить на разных уровнях, используя три XML-файла:

  • файл конфигурации приложения;

  • файл политики издателя;

  • файл конфигурации компьютера.

Эти файлы имеют одинаковый синтаксис и содержат такие сведения, как перенаправления привязки, расположение кода и режимы привязки для конкретных сборок. Каждый файл конфигурации может содержать <элемент assemblyBinding>, который перенаправляет процесс привязки. Дочерние элементы элемента <assemblyBinding> включают <элемент зависимыйAssembly.> Дочерние элементы зависимыхAssembly <> включают <элемент assemblyIdentity>,< элемент bindingRedirect> и< элемент codeBase.>

Примечание.

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

Файл конфигурации приложения

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

В случае клиентских приложений файл конфигурации приложения расположен в том же каталоге, что и исполняемый файл приложения, и имеет такое же базовое имя, но с расширением CONFIG. Например, файл конфигурации для C:\Program Files\Myapp\Myapp.exe — C:\Program Files\Myapp\Myapp.exe.config. В сценарии на основе браузера HTML-файл должен использовать <элемент ссылки> , чтобы явно указать файл конфигурации.

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

<configuration>
   <system.diagnostics>
      <trace useGlobalLock="false" autoflush="true" indentsize="0">
         <listeners>
            <add name="myListener" type="System.Diagnostics.TextWriterTraceListener, system version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" initializeData="c:\myListener.log" />
         </listeners>
      </trace>
   </system.diagnostics>
</configuration>

Файл политики издателя

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

Ниже приведен пример файла конфигурации политики издателя.

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

            <dependentAssembly>
                <assemblyIdentity name="asm6" publicKeyToken="c0305c36380ba429" />
                <bindingRedirect oldVersion="3.0.0.0" newVersion="2.0.0.0"/>
            </dependentAssembly>

        </assemblyBinding>
    </runtime>
</configuration>

Чтобы создать сборку, можно воспользоваться компоновщиком сборок (Al.exe) и выполнить команду следующего вида:

Al.exe /link:asm6.exe.config /out:policy.3.0.asm6.dll /keyfile: compatkey.dat /v:3.0.0.0

compatkey.dat — это файл ключа строгого имени. Эта команда создает сборку со строгим именем, которую можно поместить в глобальный кэш сборок.

Примечание.

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

Файл конфигурации политики издателя переопределяет сведения о версии, которые поступают от приложения (то есть из манифеста сборки или из файла конфигурации приложения). Если в файле конфигурации приложения нет оператора перенаправления версии, указанной в манифесте сборки, файл политики издателя переопределяет версию, указанную в манифесте сборки. Однако если такой оператор имеется, политика издателя переопределяет эту версию, а не версию, указанную в манифесте.

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

Безопасный режим

Файлы политики издателя обычно явным образом устанавливаются как часть пакета обновления или обновления программы. В случае возникновения проблем с обновленным общим компонентом можно проигнорировать изменения в файле политики издателя, используя безопасный режим. Безопасный режим определяется издателем <Apply="да|нет"/> элемент, расположенный только в файле конфигурации приложения. Он указывает, следует ли удалять сведения политики издателя из процесса привязки.

Безопасный режим можно задать для всего приложения или для выбранных сборок. То есть можно отключить политику для всех сборок, составляющих приложение, или включить ее для некоторых сборок, отключив для других. Чтобы выборочно применить политику издателя к сборкам, составляющим приложение, задайте publisherPolicy apply=no/> и укажите, какие сборки необходимо затронуть с помощью элемента зависимыхAssembly><.< Чтобы применить политику издателя ко всем сборкам, составляющим приложение, задайте <publisherPolicy apply=no/> без зависимых элементов сборки. Дополнительные сведения о конфигурации см. в разделе Настройка приложений с использованием файлов конфигурации.

Файл конфигурации компьютера

Файл конфигурации компьютера среда выполнения проверяет последним. Этот файл с именем Machine.config находится на локальном компьютере в подкаталоге Config корневого каталога, где установлена среда выполнения. С помощью этого файла администраторы могут настраивать ограничения привязки сборок, действующие только на этом компьютере. Параметры в файле конфигурации компьютера имеют приоритет над всеми остальными параметрами. Однако это не означает, что все параметры конфигурации должны быть помещены в этот файл. Версия, определяемая файлом политики администратора, является окончательной и не может быть переопределена. Переопределения, заданные в файле Machine.config, влияют на все приложения. Дополнительные сведения о файлах конфигурации см. в разделе Настройка приложений с использованием файлов конфигурации.

Шаг 2. Проверка наличия ранее связанных сборок

Если запрошенная сборка уже запрашивалась в предыдущих вызовах, среда CLR использует уже загруженную сборку. Это может иметь последствия при именовании сборок, составляющих приложение. Подробнее об именовании сборок см. в разделе Имена сборок.

Если предыдущий запрос сборки завершился неудачей, последующие вызовы этой сборки немедленно прерываются без попытки загрузить сборку. Начиная с платформа .NET Framework версии 2.0, ошибки привязки сборок кэшируются, а кэшированные сведения используются для определения того, следует ли пытаться загрузить сборку.

Примечание.

Чтобы вернуться к поведению платформа .NET Framework версий 1.0 и 1.1, которые не кэшировали сбои привязки, включите <элемент disableCachingBindingFailures> в файл конфигурации.

Шаг 3. Проверка глобального кэша сборок

Для сборок со строгими именами процесс привязки продолжается поиском в глобальном кэше сборок. В глобальном кэше сборок сохраняются сборки, которые могут использоваться на компьютере несколькими приложениями. Все сборки в глобальном кэше сборок должны иметь строгие имена.

Шаг 4. Обнаружение сборки с помощью базы кода или проверки

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

  1. <Если элемент codeBase> найден в файле конфигурации приложения, среда выполнения проверяет указанное расположение. Если найдено совпадение, используется эта сборка, и дальнейший поиск не выполняется. Если сборку не удается обнаружить в этом файле, происходит сбой запроса привязки.

  2. Среда выполнения осуществляет проверку наличия связанной сборки, используя правила, описанные далее в этом разделе.

Примечание.

Если в каталоге есть несколько версий сборки, и вы хотите ссылаться на определенную версию этой сборки, необходимо использовать <элемент codeBase> вместо privatePath атрибута< элемента проверки>. Если вы используете <элемент проверки,> среда выполнения останавливает проверку при первом поиске сборки, соответствующей простому имени сборки, на которую ссылается ссылка, независимо от того, соответствует ли она правильному совпадению. Если совпадение точное, найденная сборка используется. Если совпадение не является точным, проверка прекращается и происходит сбой привязки.

Обнаружение сборки с помощью базы кода

Сведения о базе кода можно предоставить с помощью <элемента CodeBase> в файле конфигурации. Эта база кода всегда проверяется, прежде чем среда выполнения переходит к проверке наличия связанной сборки. Если файл политики издателя, содержащий перенаправление последней версии, также содержит <элемент codeBase>, этот< элемент codeBase> является используемым. Например, если файл конфигурации приложения задает элемент codeBase>, а файл политики издателя, переопределяющий сведения о приложении, также указывает< элемент codeBase, <используется элемент codeBase>> в файле политики издателя.<

Если совпадение не найдено в расположении, указанном элементом <codeBase> , запрос привязки завершается ошибкой, и дальнейшие действия не выполняются. Если среда выполнения определяет, что сборка соответствует критерию вызывающей сборки, то используется эта сборка. Когда файл, указанный заданным <элементом codeBase> , загружается, среда выполнения проверяет, соответствует ли имя, версия, язык и региональные параметры и открытый ключ ссылке вызывающей сборки.

Примечание.

Ссылки на сборки за пределами корневого каталога приложения должны иметь строгие имена и должны быть установлены в глобальном кэше сборок или указаны с помощью <элемента codeBase> .

Обнаружение сборки с помощью проверки

Если в файле конфигурации приложения отсутствует <элемент CodeBase> , среда выполнения проверяет сборку с помощью четырех условий:

  • Базовая папка приложения, то есть корневой каталог, где выполняется приложение.

  • Язык и региональные параметры, то есть атрибут culture сборки, на которую задана ссылка.

  • Имя, то есть имя сборки, на которую задана ссылка.

  • Атрибут privatePath<элемента проверки> , который является определяемым пользователем списком подкаталогов в корневом расположении. Это расположение может быть задано в файле конфигурации приложения и в управляемом коде с помощью свойства AppDomainSetup.PrivateBinPath для домена приложения. При указании в управляемом коде путь privatePath управляемого кода проверяется первым. Затем проверяется путь, указанный в файле конфигурации приложения.

Проверка базовой папки приложения и каталогов языков и региональных параметров

Среда выполнения всегда начинает проверку с базовой папки приложения, которая может быть URL-адресом или корневым каталогом приложения на компьютере. Если связанная сборка не найдена в базовой папке приложения и не предоставлены сведения о языке и региональных параметрах, среда выполнения осуществляет поиск во всех подкаталогах с именем сборки. В число проверяемых каталогов входят следующие:

  • [базовая папка приложения] / [имя сборки].dll

  • [базовая папка приложения] / [имя сборки] / [имя сборки].dll

Если указаны сведения о языке и региональных параметрах, проверяются только следующие каталоги:

  • [базовая папка приложения] / [язык и региональные параметры] / [имя сборки].dll

  • [базовая папка приложения] / [язык и региональные параметры] / [имя сборки] / [имя сборки].dll

Проверка с помощью атрибута privatePath

Помимо подкаталогов языка и подкаталогов, именованных для указанной сборки, среда выполнения также проверяет каталоги, указанные с помощью privatePath атрибута< элемента проверки>. Каталоги, заданные с помощью атрибута privatePath , должны быть подкаталогами корневого каталога приложения. Проверяемые каталоги зависят от того, включены ли сведения о языке и региональных параметрах в запрос связанной сборки.

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

Если язык и региональные параметры включены, проверяются следующие каталоги:

  • [базовая папка приложения] / [binpath] / [язык и региональные параметры] / [имя сборки].dll

  • [базовая папка приложения] / [binpath] / [язык и региональные параметры] / [имя сборки] / [имя сборки].dll

Если язык и региональные параметры не включены, проверяются следующие каталоги:

  • [базовая папка приложения] / [binpath] / [имя сборки].dll

  • [базовая папка приложения] / [binpath] / [имя сборки] / [имя сборки].dll

Примеры проверки

Заданы следующие сведения:

  • Имя сборки, на которую указывает ссылка: myAssembly

  • Корневой каталог приложения: http://www.code.microsoft.com

  • <> Элемент проверки в файле конфигурации указывает: bin

  • Язык и региональные параметры: de

Среда выполнения проверяет следующие URL-адреса:

  • http://www.code.microsoft.com/de/myAssembly.dll

  • http://www.code.microsoft.com/de/myAssembly/myAssembly.dll

  • http://www.code.microsoft.com/bin/de/myAssembly.dll

  • http://www.code.microsoft.com/bin/de/myAssembly/myAssembly.dll

Несколько сборок с одинаковыми именами

В примере ниже показано, как настроить несколько сборок с одинаковыми именами.

<dependentAssembly>
   <assemblyIdentity name="Server" publicKeyToken="c0305c36380ba429" />
   <codeBase version="1.0.0.0" href="v1/Server.dll" />
   <codeBase version="2.0.0.0" href="v2/Server.dll" />
</dependentAssembly>

Другие проверяемые расположения

Расположение сборки также может быть установлено с помощью текущего контекста привязки. Это часто происходит при использовании метода Assembly.LoadFrom и в сценариях COM-взаимодействия. Если сборка использует метод LoadFrom для ссылки на другую сборку, расположение вызывающей сборки считается подсказкой для поиска расположения сборки, на которую задана ссылка. Если удается найти совпадение, эта сборка загружается. Если совпадение не найдено, среда выполнения продолжает поиск в соответствии с семантикой, а затем запрашивает установщик Windows о предоставлении сборки. Если не удается предоставить сборку, соответствующую запросу привязки, создается исключение. Это исключение TypeLoadException в управляемом коде, если была задана ссылка на тип, или FileNotFoundException , если загружаемая сборка не найдена.

Например, если сборка Assembly1 ссылается на сборку Assembly2 и сборка Assembly1 была скачана с адреса http://www.code.microsoft.com/utils, это расположение считается подсказкой для поиска Assembly2.dll. После этого среда выполнения проверяет наличие сборки в http://www.code.microsoft.com/utils/Assembly2.dll и http://www.code.microsoft.com/utils/Assembly2/Assembly2.dll. Если сборка Assembly2 не обнаружена ни в одном из этих расположений, среда выполнения отправляет запрос установщику Windows.

См. также