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

Я искал ответ на странное поведение, которое я обнаружил в разрешении сборки, но безрезультатно. Мне известно, что CLR записывает ссылки сборки в ее метаданные (манифест). Он записывает имя, номер версии, токен открытого ключа и локаль. При загрузке сборки каждая ссылка на сборку проверяется и загружается. Этот тест чувствителен к версии или, другими словами, должна быть найдена и загружена та же версия, которая использовалась в сборке, а не любая другая версия. Если сборка подписана, открытый ключ также вступает в игру.

Проблема в том, что в фиктивном приложении, которое я создал для тестирования, это правило нарушено! Я уже искал SO и Google, и ответы не в порядке. Пожалуйста, не давайте мне следующие причины, обходные пути:

  • "Определенная версия" имеет значение "Ложь": это верно только во время компиляции и не имеет никакого отношения к среде выполнения.
  • Кроме того, нет конфигурации приложения или компьютера.

В моей настройке тестирования у меня есть Project A, ссылающийся на Project B. После создания версий я меняю проект B и строю только сам, а не A. Теперь я копирую новый B.DLL с измененной версией в рабочий каталог A и запускаю A. Он работает!! Я ожидаю, что это потерпит крах.

Вывод файла Fuselogvw.exe должен быть очевиден. В журнале упоминается, что сборка должна искать версию 9, а версия 8 находится и загружается! Обратите внимание на строку:

LOG: имя сборки: dllProj, версия =1.1.10.8, культура = нейтральная, PublicKeyToken= ноль

*** Assembly Binder Log Entry  (10/8/2014 @ 2:34:51 PM) ***

The operation was successful.
Bind result: hr = 0x0. The operation completed successfully.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorwks.dll
Running under executable  C:\...\Documents\Visual Studio 2013\Projects\test1\test1\bin\Release\test1.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: User = ...
LOG: DisplayName = dllProj, Version=1.1.10.9, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/.../Documents/Visual Studio 2013/Projects/test1/test1/bin/Release/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = NULL
Calling assembly : test1, Version=1.1.1.1, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\...\Documents\Visual Studio 2013\Projects\test1\test1\bin\Release\test1.exe.Config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/.../Documents/Visual Studio 2013/Projects/test1/test1/bin/Release/dllProj.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\...\Documents\Visual Studio 2013\Projects\test1\test1\bin\Release\dllProj.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: dllProj, Version=1.1.10.8, Culture=neutral, PublicKeyToken=null
LOG: Binding succeeds. Returns assembly from C:\...\Documents\Visual Studio 2013\Projects\test1\test1\bin\Release\dllProj.dll.
LOG: Assembly is loaded in default load context.

1 ответ

Решение

В MSDN почти в конце главной страницы есть примечание мелкого шрифта о привязке сборки:

Не проводится проверка версий для сборок без строгих имен, а также проверка времени выполнения в глобальном кэше сборок для сборок без строгих имен.

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

Другие вопросы по тегам