.net - net - Каковы различия между AssemblyVersion, AssemblyFileVersion и AssemblyInformationalVersion?




c#.net attributes (5)

Вершина сборки в .NET может быть запутанной перспективой, учитывая, что в настоящее время существует как минимум три способа указать версию для вашей сборки.

Вот три основных атрибута сборки, связанные с версией:

// Assembly mscorlib, Version 2.0.0.0
[assembly: AssemblyFileVersion("2.0.50727.3521")]
[assembly: AssemblyInformationalVersion("2.0.50727.3521")]
[assembly: AssemblyVersion("2.0.0.0")]

По соглашению, четыре части версии называются основной версией , малой версией , сборкой и ревизией .

AssemblyFileVersion предназначена для уникальной идентификации сборки отдельной сборки

Обычно вы вручную устанавливаете Major and Minor AssemblyFileVersion, чтобы отображать версию сборки, а затем увеличивайте сборку и / или ревизию каждый раз, когда ваша сборка компилирует сборку. AssemblyFileVersion должен позволить вам однозначно идентифицировать сборку сборки, чтобы вы могли использовать ее в качестве отправной точки для отладки любых проблем.

В моем текущем проекте у нас есть сервер сборки, который кодирует номер списка изменений из нашего исходного хранилища управления в части сборки и пересмотра AssemblyFileVersion. Это позволяет нам напрямую сопоставлять сборку с исходным кодом для любой сборки, сгенерированной сервером сборки (без необходимости использования меток или ветвей в исходном элементе управления или для ведения любых записей выпущенных версий вручную).

Этот номер версии хранится в ресурсе версии Win32 и может быть замечен при просмотре страниц свойств проводника Windows для сборки.

CLR не заботится и не рассматривает AssemblyFileVersion.

AssemblyInformationalVersion предназначена для представления версии всего вашего продукта

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

«Например, версия 2.0 продукта может содержать несколько сборок; одна из этих сборок отмечена как версия 1.0, так как это новая сборка, которая не поставлялась в версии 1.0 того же продукта. Как правило, вы устанавливаете основную и второстепенную части этого номера версии для представления публичной версии вашего продукта. Затем вы увеличиваете части сборки и ревизии каждый раз, когда вы упаковываете полный продукт со всеми его сборками ». - Джеффри Рихтер, [CLR через C # (второе издание)] стр. 57

CLR не заботится и не рассматривает AssemblyInformationalVersion.

AssemblyVersion - единственная версия, с которой заботится CLR (но она заботится о всей AssemblyVersion )

AssemblyVersion используется CLR для привязки к сильно названным сборкам. Он хранится в таблице метаданных манифеста AssemblyDef встроенной сборки и в таблице AssemblyRef любой сборки, которая ссылается на нее.

Это очень важно, потому что это означает, что когда вы ссылаетесь на сильно названную сборку, вы тесно связаны с конкретной AssemblyVersion этой сборки. Весь AssemblyVersion должен быть точным совпадением для успешной привязки. Например, если вы ссылаетесь на версию 1.0.0.0 сильно названной сборки во время сборки, но только версия 1.0.0.1 этой сборки доступна во время выполнения, привязка не удастся! (Затем вам придется обойти это с помощью перенаправления привязки сборок .)

Путаница в отношении соответствия всей AssemblyVersion . (Да, это так.)

Существует немного путаницы вокруг того, должно ли все AssemblyVersion быть точным совпадением, чтобы сборка была загружена. Некоторые люди находятся под ложным убеждением, что только основные и второстепенные части AssemblyVersion должны соответствовать, чтобы привязка к успеху. Это разумное предположение, однако оно в конечном счете неверно (как и для .NET 3.5), и это тривиально проверить это для вашей версии CLR. Просто выполните этот пример кода .

На моей машине вторая сборка загружается, и последние две строки журнала слияния дают понять, почему:

.NET Framework Version: 2.0.50727.3521
---
Attempting to load assembly: Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f
Successfully loaded assembly: Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f
---
Attempting to load assembly: Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
Assembly binding for  failed:
System.IO.FileLoadException: Could not load file or assembly 'Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, 
PublicKeyToken=0b3305902db7183f' or one of its dependencies. The located assembly's manifest definition 
does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f'

=== Pre-bind state information ===
LOG: User = Phoenix\Dani
LOG: DisplayName = Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
 (Fully-specified)
LOG: Appbase = [...]
LOG: Initial PrivatePath = NULL
Calling assembly : AssemblyBinding, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
LOG: Attempting download of new URL [...].
WRN: Comparing the assembly name resulted in the mismatch: Revision Number
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

Я думаю, что источником этой путаницы, вероятно, является то, что Microsoft изначально планировала быть немного более мягким в отношении этого строгого соответствия всей AssemblyVersion, сопоставляя только части Major и Minor:

«При загрузке сборки CLR автоматически найдет последнюю установленную версию обслуживания, которая соответствует основной / младшей версии запрашиваемой сборки». - Джеффри Рихтер, [CLR через C # (второе издание)] стр. 56

Это было поведение в Beta 1 из 1.0 CLR, однако эта функция была удалена до выпуска 1.0 и не смогла переопределить в .NET 2.0:

«Примечание. Я только что описал, как вы должны думать о номерах версий. К сожалению, CLR не обрабатывает номера версий таким образом. [В .NET 2.0] CLR обрабатывает номер версии как непрозрачное значение, а если сборка зависит от версии 1.2.3.4 другой сборки, CLR пытается загрузить только версию 1.2.3.4 (если не применяется переадресация привязки ). Тем не менее, Microsoft планирует изменить загрузчик CLR в будущей версии, чтобы загрузить последнюю сборку / версию для данной основной / младшей версии сборки . Например, в будущей версии CLR, если загрузчик пытается найти версию 1.2.3.4 сборки и версию 1.2.5.0, загрузчик автоматически получает последнюю версию обслуживания. Это будет очень приятным изменением для загрузчика CLR - я не могу ждать ». - Джеффри Рихтер, [CLR через C # (второе издание)] стр. 164 (Акцент мой)

Поскольку это изменение все еще не реализовано, я думаю, что можно с уверенностью предположить, что Microsoft отследила это намерение, и, возможно, уже слишком поздно это менять. Я попытался найти в Интернете, чтобы узнать, что произошло с этими планами, но я не нашел ответов. Я все еще хотел разобраться.

Поэтому я отправил по электронной почте Джеффу Рихтеру и спросил его прямо - я подумал, может ли кто-нибудь узнать, что случилось, это был бы он.

Он ответил в течение 12 часов, в субботу утром, не менее, и пояснил, что загрузчик .NET 1.0 Beta 1 действительно реализовал этот механизм автоматического перемотки вперед, чтобы собрать новейшие доступные сборки и ревизии сборки, но это поведение было назад до отправки .NET 1.0. Позже это было предназначено для оживления этого, но оно не дошло до отправки CLR 2.0. Затем появился Silverlight, который стал приоритетом для команды CLR, поэтому эта функциональность затянулась еще дальше. В то же время большинство людей, которые были во времена CLR 1.0 Beta 1, с тех пор перешли, так что маловероятно, что это увидит свет дня, несмотря на всю тяжелую работу, которая уже была введена в нее.

Нынешнее поведение, похоже, здесь, чтобы остаться.

Также стоит отметить из моего обсуждения с Джеффом, что AssemblyFileVersion была добавлена ​​только после удаления механизма автоматического перемотки вперед - потому что после 1.0 Beta 1 любое изменение в AssemblyVersion было изменением для ваших клиентов, тогда негде безопасно хранить ваш номер сборки. AssemblyFileVersion - это безопасное убежище, поскольку оно никогда не проверяется автоматически CLR. Возможно, это более понятно, имея два отдельных номера версии с отдельными значениями, вместо того, чтобы пытаться сделать это разделение между Major / Minor (break) и Build / Revision (неразрывными) частями AssemblyVersion.

Суть: подумайте о том, когда вы измените свою AssemblyVersion

Мораль заключается в том, что если вы отправляете сборки, которые другие разработчики будут ссылаться, вы должны быть очень осторожны, когда вы (и не меняете) меняете AssemblyVersion этих сборок. Любые изменения в AssemblyVersion будут означать, что разработчикам приложений придется либо перекомпилировать новую версию (обновить записи AssemblyRef), либо использовать переадресацию связывания сборок, чтобы вручную переопределить привязку.

  • Не меняйте AssemblyVersion для сервисной версии, которая предназначена для обратной совместимости.
  • Измените AssemblyVersion для выпуска, который, как вы знаете, прервал изменения.

Просто взгляните на атрибуты версии mscorlib:

// Assembly mscorlib, Version 2.0.0.0
[assembly: AssemblyFileVersion("2.0.50727.3521")]
[assembly: AssemblyInformationalVersion("2.0.50727.3521")]
[assembly: AssemblyVersion("2.0.0.0")]

Обратите внимание, что именно AssemblyFileVersion содержит всю интересную информацию об обслуживании (это часть версии этой версии, которая сообщает вам, какой пакет обновления вы используете), а AssemblyVersion фиксируется в скучном старом 2.0.0.0. Любые изменения в AssemblyVersion заставят каждое приложение .NET ссылаться на mscorlib.dll на повторную компиляцию с новой версией!

Существует три атрибута сборки. Каковы различия? Это нормально, если я использую AssemblyVersion и игнорирую остальные?

MSDN говорит:

  • AssemblyVersion :

    Указывает версию приписываемой сборки.

  • AssemblyFileVersion :

    Поручает компилятору использовать определенный номер версии для ресурса версии файла Win32. Версия версии Win32 не обязана быть такой же, как номер версии сборки.

  • AssemblyInformationalVersion :

    Определяет дополнительную информацию о версии для манифеста сборки.

Это продолжение: Каковы наилучшие методы использования ассемблеров Ассамблеи?


При изменении сборки AssemblyVersion сборки, если у нее есть сильное имя, реферирующие сборки необходимо перекомпилировать, иначе сборка не загружается! Если у него нет сильного имени, если он явно не добавлен в файл проекта, он не будет скопирован для вывода каталога при сборке, поэтому вы можете пропустить определенные сборки, особенно после очистки выходного каталога.


Чтобы сохранить этот вопрос актуальным, стоит подчеркнуть, что AssemblyInformationalVersion используется NuGet и отражает версию пакета, включая любой суффикс предварительной версии.

Например, AssemblyVersion 1.0.3. *, Упакованный в asp.net core dotnet-cli

dotnet pack --version-suffix ci-7 src/MyProject

Производит пакет с версией 1.0.3-ci-7, который вы можете проверить с помощью:

CustomAttributeExtensions.GetCustomAttribute<AssemblyInformationalVersionAttribute>(asm);

AssemblyInformationalVersion и AssemblyFileVersion отображаются, когда вы просматриваете информацию «Версия» в файле через Проводник Windows, просматривая свойства файла. Эти атрибуты фактически скомпилируются в ресурс VERSION_INFO , созданный компилятором.

AssemblyInformationalVersion - это значение «Product version». AssemblyFileVersion - это значение «Версия файла».

AssemblyVersion специфичен для сборников .NET и используется загрузчиком сборки .NET, чтобы узнать, какую версию сборки загрузить / привязать во время выполнения.

Из них единственным, который абсолютно необходим .NET, является атрибут AssemblyVersion . К сожалению, это может также вызвать большинство проблем, когда оно изменяется без разбора, особенно если вы сильно назовете свои сборки.


AssemblyVersion

Там будут смотреться другие сборки, которые ссылаются на вашу сборку. Если это число изменится, другие сборки должны обновить свои ссылки на вашу сборку! Требуется AssemblyVersion .

Я использую формат: major.minor . Это приведет к:

[assembly: AssemblyVersion("1.0")]

AssemblyFileVersion

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

В Windows это можно просмотреть в свойствах файла.

Если возможно, пусть он будет создан MSBuild. AssemblyFileVersion не является обязательным. Если не указано, используется AssemblyVersion.

Я использую формат: major.minor.revision.build , где я использую ревизию для этапа разработки (Alpha, Beta, RC и RTM), пакеты обновлений и исправления. Это приведет к:

[assembly: AssemblyFileVersion("1.0.3100.1242")]

AssemblyInformationalVersion

Версия продукта сборки. Это версия, которую вы использовали бы при разговоре с клиентами или для показа на вашем веб-сайте. Эта версия может быть строкой, например « 1.0 Release Candidate ».

Анализ кода будет жаловаться на это (CA2243) - сообщил Microsoft (не фиксированный в VS2013).

AssemblyInformationalVersion является необязательным. Если не указано, используется AssemblyFileVersion.

Я использую формат: major.minor [revision as string] . Это приведет к:

[assembly: AssemblyInformationalVersion("1.0 RC1")]




attributes