Voici un blog que j'ai récemment écrit qui décrit les détails de l'assemblée de la gestion des versions...
La gestion des versions des assemblées .NET peut être une source de confusion perspective étant donné qu'il existe actuellement au moins trois façons de spécifier une version de votre assemblée.
Voici les trois principaux liés à la version de l'assemblée attributs:
// 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")]
Par convention, les quatre parties de la version sont désignés comme la Version Majeure, Mineure Version, Construire, et la Révision.
L' AssemblyFileVersion
est destiné à identifier de manière unique une accumulation de l' assemblée individuelle
Typiquement, vous allez définir manuellement la Majeure et la Mineure AssemblyFileVersion pour refléter la version de l'assemblée, puis incrémenter la construction et/ou la Révision à chaque fois que votre système de construction compile l'assemblée. Le AssemblyFileVersion devrait vous permettre d'identifier de manière unique une accumulation de l'assemblée, de sorte que vous pouvez l'utiliser comme un point de départ pour le débogage des problèmes.
Sur mon projet actuel, nous avons le serveur de build encoder la liste nombre de sources de notre référentiel de contrôle dans la construction et la Révision des pièces de la AssemblyFileVersion. Cela nous permet de mapper directement à partir d'un assembly à son code source, pour toute assemblée généré par le serveur de build (sans avoir à utiliser des étiquettes ou des branches dans le contrôle de code source, ou manuellement en gardant tous les enregistrements de versions).
Ce numéro de version est stockée dans la version Win32 de ressources et peut être vu lors de l'affichage de l'Explorateur Windows les pages de propriétés de l'assemblée.
Le CLR ne pas s'en soucier, ni examiner les AssemblyFileVersion.
L' AssemblyInformationalVersion
est destiné à représenter la version de votre produit
Le AssemblyInformationalVersion est destiné à permettre cohérente de gestion des versions de la totalité du produit, qui peut consister en de nombreuses assemblées qui sont leur propre version, peut-être avec les différentes politiques de gestion des versions, et potentiellement développés par des équipes hétérogènes.
"Par exemple, la version 2.0 d'un produit
peut contenir plusieurs assemblées; un
de ces assemblées est marqué comme
version 1.0 puisque c'est une nouvelle assemblée
qui n'a pas été livré dans la version 1.0 de l'
même produit. En règle générale, vous définissez la
majeure et mineure de cette version
nombre de représenter la version publique
de votre produit. Ensuite, vous incrémentez
la construction et la révision des pièces à chaque fois
vous créez un package d'un produit complet, avec
toutes ses assemblées."
- Jeffrey Richter, CLR via C# (Deuxième Édition) p. 57
Le CLR ne pas s'en soucier, ni examiner les AssemblyInformationalVersion.
L' AssemblyVersion
est la seule version du CLR se soucie (mais il se soucie de l'ensemble de l' AssemblyVersion
)
Le AssemblyVersion est utilisé par le CLR pour lier fortement nommé assemblées. Il est stocké dans le AssemblyDef manifeste des métadonnées de la table du construit de l'assemblée, et dans le AssemblyRef tableau de toute l'assemblée qui y fait référence.
Ceci est très important, car cela signifie que lorsque vous faites référence à un nommé fortement de l'assemblée, vous êtes étroitement lié à un AssemblyVersion de l'assemblée. L'ensemble de la AssemblyVersion doit être une correspondance exacte pour la liaison à réussir. Par exemple, si vous faites référence à la version 1.0.0.0 d'un nommé fortement de l'assemblée au moment de la construction, mais seulement la version 1.0.0.1 de cette assemblée est disponible au moment de l'exécution, la liaison échoue! (Vous serez alors obligé de contourner cela en utilisant Assembly de Redirection de Liaison.)
Confusion quant à savoir si l'ensemble de l' AssemblyVersion
doit correspondre. (Oui, c'est fait.)
Il y a un peu de confusion autour de l'ensemble de la AssemblyVersion doit être une correspondance exacte pour un assemblage à être chargé. Certains gens sont sous la fausse conviction que seule la Majeure et la Mineure de la AssemblyVersion doivent correspondre pour que la liaison à réussir. C'est une hypothèse raisonnable, mais il est en fin de compte incorrect (comme de .NET 3.5), et il est trivial de vérifier votre version du CLR. Juste exécuter cet exemple de code.
Sur ma machine de la deuxième assemblée chargement échoue, et les deux dernières lignes de la fusion du journal qu'il soit parfaitement clair pourquoi:
.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.
Je pense que la source de cette confusion est probablement parce que Microsoft à l'origine prévu pour être un peu plus indulgent sur cette stricte correspondance de la pleine AssemblyVersion, par correspondance uniquement sur la version principale et secondaire parties:
"Lors du chargement d'une assemblée, le CLR de trouver automatiquement la dernière
installé entretien de version
correspond à la majeure/mineure de la version de la
l'assemblée de la demande."
- Jeffrey Richter, CLR via C# (Deuxième Édition) p. 56
C'était le comportement de la Bêta 1 de l'1.0 CLR, cependant cette fonctionnalité a été supprimée avant la version 1.0, et n'a pas réussi à refaire surface .NET 2.0:
"Note: je viens de décrire comment vous
devrait penser à des numéros de version.
Malheureusement, le CLR ne permet pas de traiter
les numéros de version de cette façon. [.NET
2.0], le CLR traite un numéro de version opaque de la valeur, et si une assemblée
dépend de la version 1.2.3.4 de l'autre
de l'assemblée, le CLR essaie de charger
version 1.2.3.4 seulement (à moins d'une liaison
la redirection est en place). Cependant,
Microsoft a prévu de modifier la
CLR du chargeur dans une future version
qu'il se charge de la dernière
version/révision pour un majeur/mineur
la version de l'assemblée. Par exemple,
sur une future version du CLR, si l'
chargeur essaie de trouver la version
1.2.3.4 d'une assemblée et la version 1.2.5.0 existe, le chargeur avec automatiquement ramasser la dernière
l'entretien de la version. Ce sera un très
changement bienvenu de la CLR chargeur - je
pour l'un ne peut pas attendre."
- Jeffrey Richter, CLR via C# (Deuxième Édition) p. 164 (Accent
le mien)
Comme ce changement n'a pas encore été mis en œuvre, je pense qu'il est sûr de supposer que Microsoft est revenue sur cette intention, et c'est peut-être trop tard pour changer maintenant. J'ai essayé de chercher sur le web pour savoir ce qui s'est passé avec ces plans, mais je ne pouvais pas trouver toutes les réponses. J'ai toujours voulu aller au fond de lui.
J'ai donc envoyé Jeff Richter et lui a demandé directement - j'ai pensé que si quelqu'un savait ce qui s'est passé, ce serait lui.
Il a répondu dans un délai de 12 heures, un samedi matin, pas moins, et a précisé que l' .NET 1.0 Beta 1 chargeur de ne mettre en œuvre cette "automatique roll-forward" mécanisme de la cueillette jusqu'à la dernière Construire et la Révision d'un assemblage, mais ce comportement a été repris avant .NET 1.0 fourni. Plus tard, il fut destiné à relancer ce, mais il ne l'a pas fait en avant de la CLR 2.0 livré. Puis vint Silverlight, qui a la priorité pour l'équipe CLR, afin que cette fonctionnalité a été retardé de plus. Dans l'intervalle, la plupart des gens qui étaient autour de dans le jours de CLR 1.0 Beta 1 ont depuis évolué, de sorte qu'il est peu probable que cela permettra de voir la lumière du jour, en dépit de tout le travail qui avait déjà été mis en elle.
Le comportement actuel, il semble, est là pour rester.
Il est également intéressant de noter à partir de ma discussion avec Jeff qui AssemblyFileVersion n'a été ajouté après la suppression de la ‘automatique roll-forward " - parce que, après 1.0 Beta 1, toute modification de la AssemblyVersion est une modification importante pour vos clients, puis il y a eu nulle part pour stocker en toute sécurité votre numéro de build. AssemblyFileVersion est qu'un refuge sûr, comme il n'est jamais automatiquement examiné par le CLR. Peut-être que c'est plus clair de cette façon, avoir deux numéros de version, avec des significations, plutôt que d'essayer de faire que la séparation entre le Majeur/Mineur (la rupture) et de la création/Révision (sans rupture) des parties de la AssemblyVersion.
La ligne du bas: Réfléchir soigneusement lorsque vous changez AssemblyVersion
La morale est que si vous expédiez des assemblées que les autres développeurs vont être de référencement, vous devez être extrêmement prudent quand vous faites (et ne le font pas) changer le AssemblyVersion de ces assemblées. Toute modification de la AssemblyVersion signifie que les développeurs d'applications doivent re-compiler à l'encontre de la nouvelle version (mise à jour de ces AssemblyRef entrées) ou utiliser de l'assemblée de liaison des redirections pour remplacer manuellement la liaison.
-
Ne pas modifier le AssemblyVersion pour une version de maintenance qui est conçu pour être compatible en arrière.
-
Faire changer le AssemblyVersion pour une version que vous connaissez a des changements considérables.
Il suffit de prendre un autre regard sur la version attributs sur 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")]
Notez que c'est la AssemblyFileVersion qui contient toutes les intéressantes informations de service (c'est la partie Révision de cette version qui vous indique ce Service Pack, vous êtes sur la), pendant ce temps la AssemblyVersion est fixé à un ennuyeux 2.0.0.0. Toute modification de la AssemblyVersion serait forcer .NET application référencement mscorlib.dll de re-compiler avec la nouvelle version!