Redirección de enlace de ensamblaje: ¿cómo y por qué?

126

Esta no es una pregunta problemática, sino una pregunta de comprensión general sobre el funcionamiento de la redirección de enlace de ensamblaje.

Consultas

  1. ¿Por qué la redirección de enlace muestra solo versiones principales y no números menores de compilación y revisión?
  2. ¿La versión antigua y la nueva cambian solo cuando hay un cambio en la versión principal?

    <dependentAssembly>
        <assemblyIdentity name="FooBar"  
                          publicKeyToken="32ab4ba45e0a69a1"  
                          culture="en-us" />  
    
        <bindingRedirect oldVersion="7.0.0.0" newVersion="8.0.0.0" />  
    </dependentAssembly>
Nikhil Agrawal
fuente
Puede ser cualquier versión, no solo la principal. Por ejemplo:oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0"
Evk
@Evk: Todos los ejemplos que he visto muestran solo la versión principal.
Nikhil Agrawal
44
Bueno, esos son solo ejemplos, y en ninguna parte se afirma que es la única forma posible.
Evk

Respuestas:

165

¿Por qué se necesitan redireccionamientos vinculantes? Suponga que tiene la aplicación A que hace referencia a la biblioteca B, y también a la biblioteca C de la versión 1.1.2.5. La Biblioteca B a su vez también hace referencia a la biblioteca C, pero de la versión 1.1.1.0. Ahora tenemos un conflicto, porque no puede cargar diferentes versiones del mismo ensamblaje en tiempo de ejecución. Para resolver este conflicto, puede usar la redirección de enlace, generalmente a la nueva versión (pero también puede ser a la anterior). Para ello, agregue lo siguiente al archivo app.config de la aplicación A, en la configuration > runtime > assemblyBindingsección (consulte aquí un ejemplo de archivo de configuración completo):

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

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

También puede especificar un rango de versiones para asignar:

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

Ahora la biblioteca B, que se compiló con referencia a C de la versión 1.1.1.0, usará C de la versión 1.1.2.5 en tiempo de ejecución. Por supuesto, es mejor que se asegure de que la biblioteca C sea compatible con versiones anteriores o que esto pueda conducir a resultados inesperados.

Puede redirigir cualquier versión de las bibliotecas, no solo las principales.

Evk
fuente
¿En qué archivo y en qué sección van estos? ¿Alguien puede proporcionar un enlace a la fuente como MSDN o similar como referencia? Recuerde que las personas aterrizarán en sus artículos SO Q / A de todo el ámbito del motor de búsqueda y las referencias son críticas. Tuve un compañero de trabajo que me dijo que "solo agregue una redirección de ensamblado a su archivo exe" justo antes de irse de vacaciones por una semana y aterrice aquí y, aunque esta respuesta se ve muy bien, carece de contexto y referencia.
tpartee
Preguntas válidas @tpartee, he editado la respuesta (en espera de una revisión por pares) para incluir la sección de configuración y un enlace a docs.microsoft.com/en-us/dotnet/framework/configure-apps/…
Kobus Smit
1
@AlexanderDerck en el archivo de configuración de la aplicación A: no tienen ningún efecto (que yo sepa) en los archivos de configuración de las bibliotecas, excepto tal vez cuando esta biblioteca es una biblioteca de prueba unitaria y es "ejecutada" en cierto sentido por el corredor de prueba unitaria.
Evk
1
@AlexanderDerck hubo una pregunta hace un par de semanas, con muchos votos a favor e incluso recompensas, que preguntaba exactamente eso, pero nadie pudo dar una respuesta convincente - stackoverflow.com/q/48377474/5311735
Evk
1
@CodeEngine publicKeyToken identifica el ensamblado C. Solo los ensamblados firmados tienen ese token de clave pública que los identifica. Aquí hay una pregunta relacionada sobre cómo puede encontrar ese token dado que tiene ensamblado: stackoverflow.com/q/3045033/5311735
Evk
55

Encontramos un problema con la redirección de enlace para NewtonSoft.Json. Buscamos la versión del archivo en las propiedades del archivo win 10 "9.0.1.19813", buscamos el número y la redirección seguía fallando. Investigando más y descubrimos que estábamos mirando la versión del archivo y no la versión del ensamblaje. Entonces, me pregunto si la gente está confundiendo la Versión del archivo (que cambia a menudo) y la Versión del ensamblaje (que no se puede ver en el Explorador de archivos de Windows 10). Para ver la versión de ensamblaje de un dll, puede ejecutar esto en powershell. Reemplace el nombre dll con el que desea encontrar la versión.

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

El resultado de arriba es.

Major  Minor  Build  Revision

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

9      0      0      0

Ver referencias:

¿Cómo puedo ver la versión de ensamblaje de un ensamblado .NET en Windows Vista y posterior (Windows 7, 2008)?

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

ingrese la descripción de la imagen aquí

Un mito
fuente
12
¡Vota por mencionar la diferencia entre la versión de archivo y la versión de ensamblaje!
mrid