.net - net - visual studio code
¿Cómo funciona exactamente la propiedad "Versión específica" de una referencia de ensamblaje en Visual Studio? (2)
Hoy, eché un vistazo más de cerca a la propiedad "Versión específica" de las referencias de ensamblado en Visual Studio 2010. Después de algunos experimentos con resultados inesperados, me propuse aprender todo lo posible sobre cómo funciona la propiedad. Incluso SO, me parece, no tiene todas las respuestas, así que aquí está mi intento de responder la pregunta por sí mismo:
¿Cómo funciona exactamente la propiedad "Versión específica" de una referencia de ensamblaje en Visual Studio?
¡Es una propiedad de compilación!
Una de las cosas más importantes que debe saber es que la "Versión específica" es una propiedad que tiene efecto en tiempo de compilación y no en tiempo de ejecución.
¿Que es todo esto?
Cuando se construye un proyecto, las referencias de ensamblado del proyecto deben resolverse para encontrar los ensamblajes físicos que el sistema de compilación debe usar. Si se realiza la verificación de "Versión específica" (consulte la sección "¿Cuándo se verifica la" Versión específica "?), Afecta el resultado del proceso de resolución de ensamblaje:
- El sistema de compilación localiza un ensamblaje físico que potencialmente puede usar
- El sistema de compilación compara la versión del ensamblaje físico con la versión ensamblada almacenada en el archivo .csproj para la referencia de ensamblaje
- Si las dos versiones de ensamblaje son exactamente iguales, el proceso de resolución tiene éxito y el ensamblaje físico encontrado se utiliza para la construcción
- Si las dos versiones de ensamblaje no coinciden, el ensamblaje físico se descarta y el proceso de resolución continúa al ubicar el siguiente ensamblaje potencial
- Si no se pueden ubicar más conjuntos físicos potenciales, el proceso de resolución falla. Esto da como resultado una advertencia del compilador (advertencia MSB3245) que le informa que la referencia no se pudo resolver.
- ¡Curiosamente, la construcción continúa! Si el código no tiene referencias reales para el ensamblaje, la compilación tiene éxito (con la advertencia mencionada anteriormente). Si el código tiene referencias, la compilación falla con un error que parece que el código utiliza tipos desconocidos o espacios de nombres. La única indicación de por qué la compilación realmente falló es la advertencia MSB3245.
Orden en que asambleas son resueltas
El orden en el que el proceso de resolución de ensamblaje ubica los conjuntos potenciales parece ser el siguiente:
- El ensamblado al que hace referencia el elemento
<HintPath>
en el archivo .csproj - La ruta de salida del proyecto
- El GAC
Tenga en cuenta que si existen varias versiones del ensamblaje en el GAC, el proceso de resolución primero intenta resolver el ensamblado con la versión más alta. Esto es importante solo si no se realiza la verificación de "Versión específica".
¿Cuándo se verifica la "Versión específica"?
Visual Studio basa su decisión si realiza la comprobación de "Versión específica" en dos piezas de información encontradas en el archivo .csproj:
- La presencia o ausencia del elemento
<SpecificVersion>
y su valor (si está presente) - La presencia o ausencia de información de versión en la referencia de ensamblaje
Así es como se ve una referencia de ensamblaje típica con información de versión:
<Reference Include="Foo, Version=1.2.3.4, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>True</SpecificVersion>
<HintPath>../../Bar/Foo.dll</HintPath>
</Reference>
Y así es como se ve la referencia de ensamblaje sin información de versión:
<Reference Include="Foo">
[...]
La siguiente tabla muestra cuándo se realiza la verificación de "Versión específica" y cuándo no.
| Version information
| Present Not present
----------------------------+------------------------------
<SpecificVersion> |
- Present, has value True | Yes (1) Yes (check always fails) (2)
- Present, has value False | No (3) No (4)
- Not present | Yes (5) No (6)
Lo sorprendente aquí es que no se realiza ninguna comprobación si tanto <SpecificVersion>
como la información de versión están ausentes (caso 6). Hubiera esperado que la verificación se realizara y siempre fallara (igual que en el caso 2) porque, en mi entender, la ausencia de <SpecificVersion>
implica el valor predeterminado "True". Esta puede ser una peculiaridad de Visual Studio 2010 donde hice mis pruebas.
Cuando examina las propiedades de una referencia de ensamblado en la interfaz de usuario de Visual Studio (seleccione la referencia y presione F4), el valor que ve para la propiedad "Versión específica" le indica si Visual Studio va a realizar o no la "Versión específica" comprobar. En el caso 6, la interfaz de usuario mostrará "True", aunque el elemento <SpecificVersion>
no está presente en el archivo .csproj.
Efectos secundarios en "Copiar local"
Si la propiedad "Copiar local" está configurada en "Verdadero" pero el proceso de resolución del ensamblaje falla debido a la verificación de "Versión específica", no se copia ningún ensamblaje.
Material de referencia
- Lo que necesita saber sobre los ensamblados a los que se hace referencia en VS2005 (artículo blogs.msdn.com)
- ¿Qué hay de nuevo en .NET 2.0 para ensamblajes y versiones? (artículo de codemag.com que reproduce el artículo anterior de MSDN, hasta la redacción, pero contiene algunas capturas de pantalla e información adicional sobre el control de versiones del ensamblaje)
Cuando agrega una referencia, Visual Studio graba la [AssemblyVersion] del ensamblado en el archivo del proyecto. Esto es importante. Si, por ejemplo, crea una corrección de errores un año después, entonces debe asegurarse de reconstruir el proyecto con la misma versión exacta de la referencia, por lo que es un verdadero complemento. Obtendrá un error si el conjunto de referencia ha cambiado.
Pero eso no siempre es deseable. Algunos programadores permiten que la versión del ensamblaje aumente automáticamente, generando una nueva versión cada vez que se reconstruyen. Aunque la interfaz pública de la asamblea nunca cambió. Algunos configuran su proyecto usando Nuget para obtener bibliotecas y permiten que actualice automáticamente la biblioteca cuando hay una nueva versión disponible. Les gustaría establecer la propiedad Versión específica en False para suprimir el error de compilación.
Bastante importante para comprender la consecuencia, necesita volver a implementar toda la compilación del programa para evitar accidentes. Las discrepancias de versión en tiempo de ejecución bloquean el programa y solo se pueden suprimir con un <bindingRedirect>
en el archivo .config, que es arriesgado.