955 Stimmen

Was sind die Unterschiede zwischen AssemblyVersion, AssemblyFileVersion und AssemblyInformationalVersion?

Es gibt drei Attribute für Baugruppenversionen. Was sind die Unterschiede? Ist es in Ordnung, wenn ich AssemblyVersion und den Rest ignorieren?


MSDN sagt:

  • AssemblyVersion :

    Gibt die Version der zugewiesenen Baugruppe an.

  • AssemblyFileVersion :

    Weist einen Compiler an, eine bestimmte Versionsnummer für die Win32-Dateiversionsressource zu verwenden. Die Win32-Dateiversion muss nicht mit der Versionsnummer der Assembly identisch sein.

  • AssemblyInformationVersion :

    Legt zusätzliche Versionsinformationen für ein Assembly-Manifest fest.


Dies ist eine Folgemaßnahme zu Was sind die besten Praktiken für die Verwendung von Baugruppenattributen?

997voto

Rémy van Duijkeren Punkte 9607

AssemblyVersion

Wo andere Baugruppen, die auf Ihre Baugruppe verweisen, aussehen werden. Wenn sich diese Nummer ändert, müssen andere Baugruppen ihre Verweise auf Ihre Baugruppe aktualisieren! Aktualisieren Sie diese Version nur, wenn dadurch die Abwärtskompatibilität unterbrochen wird. Die AssemblyVersion erforderlich ist.

Ich verwende das Format: Major.Minor (et Haupt für sehr stabile Codebasen). Dies würde dazu führen:

[assembly: AssemblyVersion("1.3")]

Wenn Sie Folgendes verfolgen SemVer streng genommen bedeutet dies, dass Sie nur aktualisieren, wenn die Haupt Änderungen, also 1.0, 2.0, 3.0, usw.

AssemblyFileVersion

Wird für die Bereitstellung verwendet (wie Setup-Programme). Sie können diese Zahl für jede Verteilung erhöhen. Verwenden Sie sie, um Baugruppen zu markieren, die die gleiche AssemblyVersion sondern werden aus unterschiedlichen Builds und/oder Codes generiert.

Unter Windows kann sie in den Dateieigenschaften angezeigt werden.

Die AssemblyFileVersion ist optional. Wird sie nicht angegeben, wird die AssemblyVersion verwendet.

Ich verwende das Format: major.minor.patch.build , wo ich die SemVer für die ersten drei Teile und verwenden Sie die Buildnummer des Buildservers für den letzten Teil (0 für lokale Builds). Dies würde folgendes ergeben:

[assembly: AssemblyFileVersion("1.3.2.42")]

Beachten Sie, dass System.Version bezeichnet diese Teile als major.minor.build.revision !

AssemblyInformationVersion

Die Produktversion der Baugruppe. Dies ist die Version, die Sie bei Gesprächen mit Kunden oder für die Anzeige auf Ihrer Website verwenden würden. Diese Version kann eine Zeichenkette sein, wie ' 1.0 Release Candidate '.

El AssemblyInformationalVersion ist fakultativ. Wenn nicht angegeben, wird die AssemblyFileVersion verwendet.

Ich verwende das Format: major.minor[.patch] [Revision als String] . Dies würde dazu führen:

[assembly: AssemblyInformationalVersion("1.3 RC1")]

653voto

Daniel Fortunov Punkte 40842

Die Versionierung von Assemblies in .NET kann verwirrend sein, da es derzeit mindestens drei Möglichkeiten gibt, eine Version für Ihre Assembly anzugeben.

Hier sind die drei wichtigsten versionsbezogenen Baugruppenattribute:

// 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")]

Vereinbarungsgemäß werden die vier Teile der Fassung als die Hauptversion , Kleinere Version , Bauen Sie y Revision .

El AssemblyFileVersion dient der eindeutigen Identifizierung eines Builds der Einzelmontage

Normalerweise setzen Sie die Major und Minor AssemblyFileVersion manuell, um die Version der Assembly wiederzugeben, und erhöhen dann die Build und/oder Revision jedes Mal, wenn Ihr Build-System die Assembly kompiliert. Die AssemblyFileVersion sollte es Ihnen ermöglichen, einen Build der Assembly eindeutig zu identifizieren, so dass Sie ihn als Ausgangspunkt für die Fehlersuche bei Problemen verwenden können.

Auf meinem aktuellen Projekt haben wir den Build-Server kodieren die Changelist-Nummer aus unserer Source-Control-Repository in die Build und Revision Teile der AssemblyFileVersion. Dies ermöglicht uns eine direkte Zuordnung von einer Baugruppe zu ihrem Quellcode für jede vom Build-Server erzeugte Baugruppe (ohne Labels oder Zweige in der Versionsverwaltung verwenden zu müssen oder manuell Aufzeichnungen über freigegebene Versionen zu führen).

Diese Versionsnummer wird in der Win32-Versionsressource gespeichert und kann auf den Eigenschaftsseiten des Windows Explorers für die Assembly angezeigt werden.

Die CLR kümmert sich nicht um die AssemblyFileVersion und untersucht sie auch nicht.

El AssemblyInformationalVersion soll die Version Ihres gesamten Produkts darstellen

Die AssemblyInformationalVersion soll eine kohärente Versionierung des gesamten Produkts ermöglichen, das aus vielen Baugruppen bestehen kann, die unabhängig voneinander versioniert sind, möglicherweise mit unterschiedlichen Versionsrichtlinien, und die möglicherweise von verschiedenen Teams entwickelt wurden.

"Zum Beispiel kann die Version 2.0 eines Produkts mehrere Assemblies enthalten; eine dieser Baugruppen ist markiert als Version 1.0 gekennzeichnet, da es sich um eine neue Baugruppe Baugruppe ist, die nicht in der Version 1.0 des gleichen Produkts ausgeliefert wurde. Normalerweise setzen Sie die Haupt- und Nebenbestandteile dieser Versionsnummer Nummer so, dass sie die öffentliche Version Ihres Produkts. Dann inkrementieren Sie die Teile Build und Revision jedes Mal, wenn wenn Sie ein vollständiges Produkt mit all seinen Baugruppen." - Jeffrey Richter, [CLR via C# (Second Edition)] S. 57

Die CLR kümmert sich nicht um die AssemblyInformationalVersion und untersucht sie auch nicht.

El AssemblyVersion ist die einzige Version, um die sich die CLR kümmert (aber sie kümmert sich um die gesamte AssemblyVersion )

Die AssemblyVersion wird von der CLR verwendet, um an stark benannte Assemblies zu binden. Sie wird in der AssemblyDef-Manifest-Metadatentabelle der erstellten Assembly und in der AssemblyRef-Tabelle jeder Assembly, die darauf verweist, gespeichert.

Dies ist sehr wichtig, denn es bedeutet, dass Sie, wenn Sie auf eine streng benannte Baugruppe verweisen, fest an eine bestimmte AssemblyVersion dieser Baugruppe gebunden sind. Die gesamte AssemblyVersion muss genau übereinstimmen, damit die Bindung erfolgreich ist. Wenn Sie beispielsweise zur Build-Zeit auf Version 1.0.0.0 einer streng benannten Assembly verweisen, zur Laufzeit aber nur Version 1.0.0.1 dieser Assembly verfügbar ist, schlägt die Bindung fehl! (Sie müssen dieses Problem dann mit Baugruppenbindung Umlenkung .)

Verwirrung darüber, ob die gesamte AssemblyVersion muss übereinstimmen. (Ja, das muss sie.)

Es herrscht ein wenig Verwirrung darüber, ob die gesamte AssemblyVersion exakt übereinstimmen muss, damit eine Baugruppe geladen werden kann. Manche Leute glauben, dass nur der Major- und Minor-Teil der AssemblyVersion übereinstimmen müssen, damit die Bindung erfolgreich ist. Dies ist eine vernünftige Annahme, die jedoch letztlich falsch ist (ab .NET 3.5), und es ist trivial, dies für Ihre Version der CLR zu überprüfen. Führen Sie einfach aus dieses Codebeispiel .

Auf meinem Rechner schlägt das zweite Laden der Baugruppe fehl, und aus den letzten beiden Zeilen des Fusionsprotokolls geht klar hervor, warum:

.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.

Ich denke, die Quelle dieser Verwirrung liegt wahrscheinlich darin, dass Microsoft ursprünglich beabsichtigte, bei dieser strengen Abstimmung der vollständigen AssemblyVersion etwas nachsichtiger zu sein und nur die Teile Major und Minor Version abzustimmen:

"Wenn eine Baugruppe geladen wird, findet die CLR automatisch die letzte installierte Wartungsversion, die die mit der Haupt-/Nebenversion der angeforderten Baugruppe entspricht." - Jeffrey Richter, [CLR via C# (Second Edition)] S. 56

Dies war das Verhalten in Beta 1 der CLR 1.0, jedoch wurde diese Funktion vor der Veröffentlichung von 1.0 entfernt und hat es nicht geschafft, in .NET 2.0 wieder aufzutauchen:

"Hinweis: Ich habe gerade beschrieben, wie Sie über Versionsnummern nachdenken sollten. Leider geht die CLR nicht so mit Versionsnummern nicht auf diese Weise. [In .NET 2.0] behandelt die CLR eine Versionsnummer als einen undurchsichtigen Wert, und wenn eine Assembly von der Version 1.2.3.4 einer anderen Assembly abhängt, versucht die CLR, die nur die Version 1.2.3.4 zu laden (es sei denn, eine Umleitung vorhanden ist). Allerdings, Microsoft plant die Änderung des CLR-Loader in einer zukünftigen Version so zu dass er die neueste Build/Revision für eine bestimmte Major/Minor Version einer Baugruppe . Zum Beispiel, in einer zukünftigen Version der CLR, wenn der Lader versucht, die Version 1.2.3.4 einer Assembly zu finden, während die Version 1.2.5.0 existiert, wird der Lader automatisch die neueste Version verwenden. Dies wird eine sehr willkommene Änderung für den CLR-Loader sein - I kann es kaum erwarten." - Jeffrey Richter, [CLR via C# (Second Edition)] S. 164 (Hervorhebung meine)

Da diese Änderung immer noch nicht umgesetzt wurde, kann man wohl davon ausgehen, dass Microsoft diese Absicht wieder rückgängig gemacht hat, und dass es jetzt vielleicht zu spät ist, dies zu ändern. Ich habe versucht, im Internet zu recherchieren, um herauszufinden, was aus diesen Plänen geworden ist, aber ich konnte keine Antworten finden. Trotzdem wollte ich der Sache auf den Grund gehen.

Also habe ich Jeff Richter angemailt und ihn direkt gefragt - ich dachte, wenn jemand weiß, was passiert ist, dann er.

Er antwortete innerhalb von 12 Stunden, und das an einem Samstagmorgen, und stellte klar, dass der .NET 1.0 Beta 1 Loader diesen "automatischen Roll-Forward"-Mechanismus zur Übernahme des letzten verfügbaren Builds und der letzten Revision einer Assembly implementiert hatte, dass dieses Verhalten aber vor der Auslieferung von .NET 1.0 rückgängig gemacht wurde. Später sollte dieser Mechanismus wieder eingeführt werden, aber er wurde nicht vor der Veröffentlichung der CLR 2.0 eingeführt. Dann kam Silverlight, das für das CLR-Team Priorität hatte, so dass sich diese Funktionalität weiter verzögerte. In der Zwischenzeit sind die meisten Leute, die in den Tagen von CLR 1.0 Beta 1 dabei waren, weitergezogen, so dass es unwahrscheinlich ist, dass diese Funktion das Licht der Welt erblicken wird, trotz all der harten Arbeit, die bereits in sie investiert wurde.

Das derzeitige Verhalten scheint zu bleiben.

Es ist auch erwähnenswert, aus meiner Diskussion mit Jeff, dass AssemblyFileVersion wurde nur nach der Beseitigung der "automatischen Roll-forward"-Mechanismus hinzugefügt - weil nach 1.0 Beta 1, jede Änderung der AssemblyVersion war ein brechen Änderung für Ihre Kunden, gab es dann nirgendwo sicher zu speichern Ihre Build-Nummer. AssemblyFileVersion ist dieser sichere Hafen, da es nie automatisch von der CLR untersucht wird. Vielleicht ist es klarer auf diese Weise, mit zwei separaten Versionsnummern, mit separaten Bedeutungen, anstatt zu versuchen, diese Trennung zwischen der Major/Minor (Breaking) und die Build/Revision (non-breaking) Teile der AssemblyVersion zu machen.

Die Quintessenz: Überlegen Sie sorgfältig, wann Sie Ihre AssemblyVersion

Die Moral von der Geschicht' ist, dass Sie, wenn Sie Baugruppen ausliefern, auf die andere Entwickler verweisen werden, extrem vorsichtig sein müssen, wenn Sie die AssemblyVersion dieser Baugruppen ändern (und nicht ändern). Jede Änderung der AssemblyVersion bedeutet, dass Anwendungsentwickler entweder mit der neuen Version neu kompilieren müssen (um die AssemblyRef-Einträge zu aktualisieren) oder Assembly-Bindungsumleitungen verwenden müssen, um die Bindung manuell außer Kraft zu setzen.

  • Nicht die AssemblyVersion für eine Wartungsversion ändern, die abwärtskompatibel sein soll.
  • Do die AssemblyVersion für eine Version ändern, von der Sie wissen, dass sie bahnbrechende Änderungen enthält.

Schauen Sie sich einfach noch einmal die Versionsattribute von mscorlib an:

// 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")]

Beachten Sie, dass es die AssemblyFileVersion ist, die alle interessanten Wartungsinformationen enthält (es ist der Revisionsteil dieser Version, der Ihnen sagt, auf welchem Service Pack Sie sich befinden), während die AssemblyVersion auf eine langweilige alte 2.0.0.0 festgelegt ist. Jede Änderung der AssemblyVersion würde jede .NET-Anwendung, die mscorlib.dll referenziert, dazu zwingen, mit der neuen Version neu zu kompilieren!

47voto

Bob King Punkte 24518

AssemblyVersion bleibt weitgehend intern in .NET, während AssemblyFileVersion ist das, was Windows sieht. Wenn Sie zu den Eigenschaften einer Baugruppe in einem Verzeichnis gehen und auf die Registerkarte Version wechseln, wird die AssemblyFileVersion ist das, was Sie oben sehen werden. Wenn Sie Dateien nach Version sortieren, wird dies vom Explorer verwendet.

El AssemblyInformationalVersion bezieht sich auf die "Produktversion" und ist ausschließlich für den "menschlichen Gebrauch" gedacht.

AssemblyVersion ist sicherlich das Wichtigste, aber ich würde es nicht auslassen AssemblyFileVersion entweder. Wenn Sie keine AssemblyInformationalVersion Der Compiler fügt sie für Sie hinzu, indem er den Teil "Revision" Ihrer Versionsnummer entfernt und die Angaben major.minor.build belässt.

29voto

Scott Dorman Punkte 41206

AssemblyInformationalVersion y AssemblyFileVersion werden angezeigt, wenn Sie die "Versions"-Informationen einer Datei über den Windows Explorer in den Dateieigenschaften anzeigen. Diese Attribute werden zu einer VERSION_INFO Ressource, die vom Compiler erstellt wird.

AssemblyInformationalVersion ist der Wert "Produktversion". AssemblyFileVersion ist der Wert "Dateiversion".

El AssemblyVersion ist spezifisch für .NET-Assemblies und wird vom .NET-Assembly-Loader verwendet, um zu wissen, welche Version einer Assembly zur Laufzeit geladen/gebunden werden soll.

Von diesen ist die einzige, die von .NET unbedingt benötigt wird, die AssemblyVersion Attribut. Leider kann es auch die meisten Probleme verursachen, wenn es wahllos geändert wird, insbesondere wenn Sie Ihre Baugruppen stark benennen.

12voto

KCD Punkte 9257

Um diese Frage aktuell zu halten, sei darauf hingewiesen, dass AssemblyInformationalVersion wird von NuGet verwendet und spiegelt die Paket-Version einschließlich des Suffixes "pre-release".

Zum Beispiel eine AssemblyVersion von 1.0.3.*, die mit dem asp.net core dotnet-cli verpackt ist

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

Erzeugt ein Paket mit der Version 1.0.3-ci-7, das Sie mit reflection inspizieren können:

CustomAttributeExtensions.GetCustomAttribute<AssemblyInformationalVersionAttribute>(asm);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X