Как конкретно свойство "Специфическая версия" ссылки на сборку работает в Visual Studio?

Сегодня я более подробно рассмотрел свойство "Специфическая версия" ссылок на сборки в Visual Studio 2010. После нескольких экспериментов с неожиданными результатами я решил как можно больше узнать о том, как работает свойство. Даже SO, как мне кажется, не имеет всех ответов, так вот моя попытка ответить на вопрос:

Как точно использует ли свойство "Специфическая версия" ссылки на сборку в Visual Studio?

Ответ 1

Это свойство времени компиляции!

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

В чем дело?

Когда проект построен, ссылки на сборку проекта необходимо решить, чтобы найти физические сборки, которые должна использовать система сборки. Если выполняется проверка "Специфическая версия" (см. Раздел "Когда" Определенная версия "отмечена?" ), Это влияет на результат процесса разрешения сборки:

  • Система сборки обнаруживает физическую сборку, которая может потенциально использовать
  • Система сборки сравнивает версию физической сборки с версией сборки, хранящейся в файле .csproj, для ссылки на сборку
  • Если две версии сборки одинаковы, процесс разрешения завершается успешно и найденная физическая сборка используется для сборки
  • Если две версии сборки не совпадают, физическая сборка отбрасывается и процесс разрешения продолжается путем размещения следующей потенциальной сборки.
  • Если не может быть обнаружено больше потенциальных физических сборок, процесс разрешения не выполняется. Это приводит к предупреждению компилятора (предупреждение MSB3245), в котором говорится, что ссылка не может быть решена.
  • Интересно, что сборка продолжается! Если код не имеет фактических ссылок на сборку, сборка завершается успешно (с ранее упомянутым предупреждением). Если код имеет ссылки, сборка выходит из строя с ошибкой, которая выглядит так, как если бы код использовал неизвестные типы или пространства имен. Единственным признаком, почему сборка действительно не удалось, является предупреждение MSB3245.

Порядок, в котором разрешены сборки

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

  • Сборка, на которую ссылается элемент <HintPath> в файле .csproj
  • Выходной путь проекта
  • GAC

Обратите внимание, что если в GAC существует несколько версий сборки, процесс разрешения сначала пытается разрешить сборку с самой высокой версией. Это важно, только если проверка "Специфическая версия" не выполнена.

Когда установлен флажок "Определенная версия"?

Visual Studio основывает свое решение, выполнять ли проверку "конкретной версии" на двух фрагментах информации, найденных в файле .csproj:

  • Наличие или отсутствие элемента <SpecificVersion> и его значение (если оно присутствует)
  • Наличие или отсутствие информации о версии в ссылке на сборку

Вот как выглядит типичная ссылка на сборку с информацией о версии:

<Reference Include="Foo, Version=1.2.3.4, Culture=neutral, processorArchitecture=MSIL">
  <SpecificVersion>True</SpecificVersion>
  <HintPath>..\..\Bar\Foo.dll</HintPath>
</Reference>

И вот как выглядит ссылка на сборку без информации о версии:

<Reference Include="Foo">
[...]

В следующей таблице показано, когда выполняется проверка "Специфическая версия" , а когда нет.

                            |     Version information
                            |  Present       Not present
----------------------------+------------------------------
<SpecificVersion>           |
- Present, has value True   |    Yes (1)        Yes (check always fails) (2)
- Present, has value False  |    No  (3)        No (4)
- Not present               |    Yes (5)        No (6)

Удивительно то, что проверка не выполняется, если отсутствуют как <SpecificVersion>, так и информация о версии (случай 6). Я бы ожидал, что проверка будет выполнена и всегда терпит неудачу (так же, как и в случае 2), поскольку в моем понимании отсутствие <SpecificVersion> подразумевает значение по умолчанию "True". Это может быть причудой Visual Studio 2010, где я провел тесты.

Когда вы изучаете свойства ссылки на сборку в пользовательском интерфейсе Visual Studio (выберите ссылку и нажмите F4), значение, которое вы видите для свойства "Специфическая версия" , указывает вам, будет ли Visual Studio выполнять "Специфическая версия". В случае 6 UI отобразит "True", хотя элемент <SpecificVersion> отсутствует в файле .csproj.

Побочные эффекты на "Копировать локальные"

Если для свойства "Копировать локальное" установлено значение "Истина", но процесс разрешения сборки не выполняется из-за проверки "Специфическая версия" , сборка не копируется.

Справочный материал

Ответ 2

Когда вы добавляете ссылку, Visual Studio записывает [AssemblyVersion] сборки в файл проекта. Это важно. Если вы, скажем, создадите исправление ошибок через год, то вы хотите убедиться, что вы перестраиваете проект с той же версией ссылки, чтобы это было истинное падение. Вы получите сообщение об ошибке, если ссылочная сборка изменилась.

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

Довольно важно понять последствия, вам нужно перераспределить всю сборку программы, чтобы избежать несчастных случаев. Ошибка версий во время выполнения сбой программы и может быть подавлена ​​только с помощью <bindingRedirect> в файле .config, который является рискованным.