Redirection de liaison d'assembly: comment et pourquoi?

127

Ce n'est pas une question problématique mais une question de compréhension générale sur le fonctionnement de la redirection de liaison d'assembly.

Requêtes

  1. Pourquoi la redirection de liaison n'affiche que la version majeure et non les numéros mineurs, de construction et de révision?
  2. L'ancienne et la nouvelle version changent-elles uniquement en cas de modification de la version principale?

    <dependentAssembly>
        <assemblyIdentity name="FooBar"  
                          publicKeyToken="32ab4ba45e0a69a1"  
                          culture="en-us" />  
    
        <bindingRedirect oldVersion="7.0.0.0" newVersion="8.0.0.0" />  
    </dependentAssembly>
    
Nikhil Agrawal
la source
Cela peut être n'importe quelle version, pas seulement la principale. Par exemple:oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0"
Evk
@Evk: Tous les exemples que j'ai vus montrent uniquement la version majeure.
Nikhil Agrawal
4
Eh bien, ce ne sont que des exemples, et il n'est indiqué nulle part que c'est le seul moyen possible.
Evk

Réponses:

166

Pourquoi des redirections de liaison sont-elles nécessaires? Supposons que vous ayez l'application A qui référence la bibliothèque B, ainsi que la bibliothèque C de la version 1.1.2.5. La bibliothèque B fait également référence à la bibliothèque C, mais de la version 1.1.1.0. Nous avons maintenant un conflit, car vous ne pouvez pas charger différentes versions du même assembly lors de l'exécution. Pour résoudre ce conflit, vous pouvez utiliser la redirection de liaison, généralement vers la nouvelle version (mais peut également l'être vers l'ancienne). Pour ce faire, ajoutez ce qui suit au fichier app.config de l'application A, sous la configuration > runtime > assemblyBindingsection (voir ici un exemple de fichier de configuration complet):

<dependentAssembly>
    <assemblyIdentity name="C"  
                      publicKeyToken="32ab4ba45e0a69a1"  
                      culture="en-us" />  

    <bindingRedirect oldVersion="1.1.1.0" newVersion="1.1.2.5" />  
</dependentAssembly>

Vous pouvez également spécifier une plage de versions à mapper:

<bindingRedirect oldVersion="0.0.0.0-1.1.1.0" newVersion="1.1.2.5" />  

Maintenant, la bibliothèque B, qui a été compilée en référence à C de la version 1.1.1.0 utilisera C de la version 1.1.2.5 au moment de l'exécution. Bien sûr, vous feriez mieux de vous assurer que la bibliothèque C est rétrocompatible, sinon cela pourrait conduire à des résultats inattendus.

Vous pouvez rediriger toutes les versions de bibliothèques, pas seulement les principales.

Evk
la source
Dans quel dossier et dans quelle section ces éléments sont-ils placés? Quelqu'un peut-il s'il vous plaît fournir un lien vers une source comme MSDN ou similaire pour référence? N'oubliez pas que les gens vont atterrir sur vos articles SO Q / A de partout dans la sphère des moteurs de recherche et les références sont essentielles. Un collègue m'a dit de "simplement ajouter une redirection d'assemblage à votre fichier exe" juste avant de partir en vacances pendant une semaine et j'ai atterri ici et même si cette réponse semble excellente, elle manque de contexte et de référence.
tpartee
Questions valides @tpartee, j'ai modifié la réponse (en attente d'examen par les pairs) pour inclure la section de configuration et un lien vers docs.microsoft.com/en-us/dotnet/framework/configure-apps/…
Kobus Smit
1
@AlexanderDerck dans le fichier de configuration de l'application A - ils n'ont aucun effet (pour autant que je sache) dans les fichiers de configuration des bibliothèques, sauf peut-être lorsque cette bibliothèque est une bibliothèque de tests unitaires et est "exécutée" dans un certain sens par le lanceur de tests unitaires.
Evk
1
@AlexanderDerck, il y avait une question il y a quelques semaines, avec de nombreux votes positifs et même des primes, ce qui demandait exactement cela, mais personne n'a été en mesure de fournir une réponse convaincante - stackoverflow.com/q/48377474/5311735
Evk
1
@CodeEngine publicKeyToken identifie l'assembly C. Seuls les assemblys signés ont ce jeton de clé publique qui les identifie. Voici une question connexe sur la façon dont vous pouvez trouver ce jeton étant donné que vous avez l'assemblage: stackoverflow.com/q/3045033/5311735
Evk
56

Nous avons rencontré un problème avec la redirection de liaison pour NewtonSoft.Json. Nous avons recherché la version du fichier dans les propriétés du fichier win 10 "9.0.1.19813", recherché le numéro et la redirection a échoué. Une enquête plus approfondie et nous avons constaté que nous recherchions la version du fichier et non la version de l'assembly. Donc, je me demande si les gens se trompent sur la version du fichier (qui change souvent) et la version de l'assemblage (que vous ne pouvez pas voir dans l'explorateur de fichiers Windows 10). Pour voir la version Assembly d'une dll, vous pouvez l'exécuter dans PowerShell. Remplacez le nom de la dll par celui dont vous souhaitez rechercher la version.

[Reflection.AssemblyName]::GetAssemblyName('C:\development\bin\Newtonsoft.Json.dll').Version

Le résultat de ci-dessus est.

Major  Minor  Build  Revision

-----  -----  -----  --------

9      0      0      0

Voir les références:

Comment puis-je voir la version d'assemblage d'un assemblage .NET dans Windows Vista et les versions ultérieures (WIndows 7, 2008)?

https://support.microsoft.com/en-nz/help/556041

entrez la description de l'image ici

Un mythe
la source
12
Upvote pour avoir fait la différence entre la version de fichier et la version d'assemblage !!
mrid