Номера версий сборки, подписанные сборки, почему я получаю FileLoadExceptions

#.net #versioning #.net-assembly #fileloadexception

#.net #управление версиями #.net-сборка #fileloadexception

Вопрос:

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

У меня есть подписанная сборка 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…
  

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

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

Комментарии:

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

2. Я изначально не вводил никакого кода, потому что на самом деле это не проблема с кодированием. Все, что мне нужно сделать, это создать экземпляр класса из подписанной сборки, который затем пройдет через исключение. т.е. Class2 c = new Class2();

Ответ №1:

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

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

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

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

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

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

Комментарии:

1. Вы правы, «Конкретная версия» — это свойство времени компиляции. Моя ошибка.

Ответ №2:

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

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

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

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

Комментарии:

1. Свойство «Конкретная версия» для ссылки на сборку — это только проверка версии во время компиляции. Он не используется во время выполнения. Поэтому, даже если я установлю для этого значение false, это не повлияет на время выполнения. По-прежнему возникает та же ошибка.

2. Да, я определенно ошибся. Здесь есть хорошая тема по этой теме: social.msdn.microsoft.com/Forums/en-US/csharpide/thread /…