Перенаправление привязки сборки: как и почему?

127

Это не проблемный вопрос, а общий вопрос о работе перенаправления привязки сборки.

Запросы

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

    <dependentAssembly>
        <assemblyIdentity name="FooBar"  
                          publicKeyToken="32ab4ba45e0a69a1"  
                          culture="en-us" />  
    
        <bindingRedirect oldVersion="7.0.0.0" newVersion="8.0.0.0" />  
    </dependentAssembly>
    
Нихил Агравал
источник
Это может быть любая версия, а не только основная. Например:oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0"
Evk
@Evk: Все примеры, которые я видел, показывают только основную версию.
Nikhil Agrawal
4
Что ж, это всего лишь примеры, и нигде не говорится, что это единственно возможный способ.
Evk

Ответы:

166

Зачем вообще нужны обязательные перенаправления? Предположим, у вас есть приложение A, которое ссылается на библиотеку B, а также на библиотеку C версии 1.1.2.5. Библиотека B, в свою очередь, также ссылается на библиотеку C, но версии 1.1.1.0. Теперь у нас конфликт, потому что вы не можете загружать разные версии одной и той же сборки во время выполнения. Чтобы разрешить этот конфликт, вы можете использовать перенаправление привязки, обычно к новой версии (но может быть и к старой). Вы делаете это, добавляя следующее в файл app.config приложения A в configuration > runtime > assemblyBindingразделе (см. Здесь пример полного файла конфигурации):

<dependentAssembly>
    <assemblyIdentity name="C"  
                      publicKeyToken="32ab4ba45e0a69a1"  
                      culture="en-us" />  

    <bindingRedirect oldVersion="1.1.1.0" newVersion="1.1.2.5" />  
</dependentAssembly>

Вы также можете указать диапазон версий для сопоставления:

<bindingRedirect oldVersion="0.0.0.0-1.1.1.0" newVersion="1.1.2.5" />  

Теперь библиотека B, которая была скомпилирована со ссылкой на C версии 1.1.1.0, будет использовать C версии 1.1.2.5 во время выполнения. Конечно, вам лучше убедиться, что библиотека C имеет обратную совместимость, иначе это может привести к неожиданным результатам.

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

Evk
источник
В какой файл и в какой раздел они входят? Может ли кто-нибудь предоставить ссылку на источник, такой как MSDN или аналогичный, для справки? Помните, что люди будут попадать на ваши статьи SO Q / A со всех концов поисковой системы, а ссылки имеют решающее значение. У меня был коллега, который сказал мне «просто добавить перенаправление сборки в ваш exe-файл» прямо перед поездкой в ​​отпуск на неделю, и я приземлился здесь, и, хотя этот ответ выглядит великолепно, ему не хватает контекста и ссылки.
участник
Правильные вопросы @tpartee, я отредактировал ответ (ожидаю экспертной оценки), включив в него раздел конфигурации и ссылку на docs.microsoft.com/en-us/dotnet/framework/configure-apps/…
Kobus Smit
1
@AlexanderDerck в конфигурационном файле приложения A - они не имеют никакого эффекта (насколько мне известно) в конфигурационных файлах библиотек, за исключением, возможно, тех случаев, когда эта библиотека является библиотекой модульного тестирования и в некотором смысле "выполняется" средством запуска модульного теста.
Evk
1
@AlexanderDerck пару недель назад был вопрос с множеством голосов и даже наградой, который задавал именно это, но никто не смог дать убедительного ответа - stackoverflow.com/q/48377474/5311735
Evk
1
@CodeEngine publicKeyToken идентифицирует сборку C. Только подписанные сборки имеют этот токен открытого ключа, идентифицирующий их. Вот связанный с этим вопрос о том, как узнать этот токен, если у вас есть сборка: stackoverflow.com/q/3045033/5311735
Evk
56

Мы столкнулись с проблемой перенаправления привязки для NewtonSoft.Json. Мы посмотрели версию файла в свойствах файла win 10 «9.0.1.19813», посмотрели номер, и перенаправление продолжало терпеть неудачу. Дальнейшее расследование показало, что мы смотрели на версию файла, а не на версию сборки. Итак, мне интересно, не путают ли люди версию файла (которая часто меняется) и версию сборки (которую вы не видите в проводнике Windows 10). Чтобы увидеть сборочную версию DLL, вы можете запустить ее в PowerShell. Замените имя dll на то, для которого вы хотите найти версию.

[Reflection.AssemblyName]::GetAssemblyName('C:\development\bin\Newtonsoft.Json.dll').Version

Результат выше.

Major  Minor  Build  Revision

-----  -----  -----  --------

9      0      0      0

См. Ссылки:

Как я могу увидеть версию сборки .NET в Windows Vista и новее (WIndows 7, 2008)?

https://support.microsoft.com/en-nz/help/556041

введите описание изображения здесь

Amyth
источник
12
Проголосуйте за то, что подчеркнули разницу между версией файла и версией сборки !!
mrid