Номера версий сборок, подписанные сборки Почему я получаю FileLoadExceptions - PullRequest
2 голосов
/ 15 октября 2011

Моя проблема:

У меня есть подписанная сборка A.dll, которая имеет версию 1.0.0.0 У меня есть другая сборка (скажем, B.dll), которая ссылается на A.dll.

Как только обе сборки загружаются нормально, без проблем. Теперь, если версия A.dll меняется на 1.0.0.1 и перекомпилируется, нужно ли перекомпилировать B.dll?

Я спрашиваю, потому что у меня есть точный сценарий, когда после того, как A.dll изменила свою версию, я теперь получаю следующее исключение при попытке загрузить B.dll:

Unhandled Exception: System.IO.FileLoadException: 
    Could not load file or assembly A, Version=1.0.0.0, 
    Culture=neutral, PublicKeyToken…

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

Какой сценарий / условия вызывают это исключение? Если кто-то может предложить какое-то понимание этого, это будет с благодарностью. Спасибо.

Ответы [ 2 ]

2 голосов
/ 26 октября 2011

Когда сборка строго названа, все, что ссылается на нее, будет искать эту конкретную версию.

Вы правы в том, что «Конкретная версия» в Visual Studio никак не влияет на среду выполнения. Фактически, «Конкретная версия» в основном означает «Когда вы запускаете сборку, если MSBUILD не может найти версию, на которую ссылалась, произойдет сбой сборки или просто используется следующая версия, которая может быть найдена в файловой системе?»

Если вы перекомпилируете A и развернете его как частичное обновление (а не полностью развернутое приложение), то, если в приложении есть что-то, ссылающееся на старую версию, ваше приложение может сломаться, если у вас все еще нет также доступна старая версия A (т.е. вы ее не перезаписывали).

Это основная причина, по которой некоторые продукты используют GAC, потому что он может хранить несколько версий одной и той же DLL без перезаписи друг друга - если вы пытались развернуть разные версии одного и того же файла в папке bin (при условии, что они имели имя файла, которое они обычно делают), они будут перезаписывать друг друга, и в результате вы получите только одну из DLL в вашем продукте!

Еще один трюк, который вы можете сделать, это поместить ваши «обновленные» библиотеки DLL в подпапку в двоичном каталоге и отредактировать файл app.config, чтобы сообщить среде выполнения, где их искать. http://support.microsoft.com/kb/837908

Итак, чтобы подвести итог, сборка со строгим именем использует не только простое имя для определения идентификатора сборки - изменение ее версии можно рассматривать как полное изменение ее имени.

1 голос
/ 15 октября 2011

Независимо от того, подписана ли сборка А, это не обязательно имеет значение. Скомпилировали ли вы «Specific Version = true» в ссылке на сборку проекта B для A? Если это так, то CLR будет использовать строгие правила, чтобы определить, является ли данная версия A приемлемой. Если нет, то CLR будет использовать менее строгие правила, и вам не нужно будет перекомпилировать, если A увеличивает свою версию.

В зависимости от вашей среды вы можете не беспокоиться о том, что A нарушит совместимость в будущей версии. Если вас это не беспокоит, вам следует изменить ссылки на сборку на «Specific Version = false». (На работе у нас есть обе ситуации: например, когда мы зависим от стороннего элемента управления, мы обычно устанавливаем «Specific Version = true», но когда мы потребляем внутренний компонент общего доступа, который мы будем тестировать на соответствие приложения, которые его используют, мы удостоверимся, что «Specific Version = false», поэтому нам не нужно перекомпилировать.)

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

Надеюсь, это поможет!

...