.NET 4.0 tiene un nuevo GAC, ¿por qué?

Resuelto Max Toro asked hace 14 años • 4 respuestas

%windir%\Microsoft.NET\assembly\es el nuevo GAC . ¿Significa que ahora tenemos que administrar dos GAC, uno para aplicaciones .NET 2.0-3.5 y otro para aplicaciones .NET 4.0?

La pregunta es, ¿por qué?

Max Toro avatar Apr 18 '10 05:04 Max Toro
Aceptado

Sí, dado que hay 2 cachés de ensamblaje global (GAC) distintas, deberá administrar cada una de ellas individualmente.

En .NET Framework 4.0, el GAC pasó por algunos cambios. El GAC se dividió en dos, uno para cada CLR.

La versión de CLR utilizada tanto para .NET Framework 2.0 como para .NET Framework 3.5 es CLR 2.0. En las dos versiones anteriores del marco no había necesidad de dividir GAC. El problema de romper aplicaciones antiguas en Net Framework 4.0.

Para evitar problemas entre CLR 2.0 y CLR 4.0, el GAC ahora se divide en GAC privados para cada tiempo de ejecución. El cambio principal es que las aplicaciones CLR v2.0 ahora no pueden ver los ensamblados de CLR v4.0 en el GAC.

Fuente

¿Por qué?

Parece deberse a que hubo un cambio de CLR en .NET 4.0 pero no en 2.0 a 3.5. Lo mismo sucedió con 1.1 a 2.0 CLR. Parece que el GAC tiene la capacidad de almacenar diferentes versiones de ensamblados siempre que sean del mismo CLR. No quieren romper aplicaciones antiguas.

Consulte la siguiente información en MSDN sobre los cambios de GAC en 4.0 .

Por ejemplo, si tanto .NET 1.1 como .NET 2.0 comparten el mismo GAC, entonces una aplicación .NET 1.1, al cargar un ensamblado desde este GAC compartido, podría obtener ensamblados .NET 2.0, rompiendo así la aplicación .NET 1.1.

La versión de CLR utilizada tanto para .NET Framework 2.0 como para .NET Framework 3.5 es CLR 2.0. Como resultado de esto, en las dos versiones anteriores del marco no hubo necesidad de dividir el GAC. El problema de romper aplicaciones antiguas (en este caso, .NET 2.0) resurge en Net Framework 4.0, momento en el que se lanzó CLR 4.0. Por lo tanto, para evitar problemas de interferencia entre CLR 2.0 y CLR 4.0, el GAC ahora se divide en GAC privados para cada tiempo de ejecución.

A medida que CLR se actualice en versiones futuras, puede esperar lo mismo. Si solo cambia el idioma, entonces puede usar el mismo GAC.

Brian R. Bondy avatar Apr 17 '2010 22:04 Brian R. Bondy

También quería saber por qué 2 GAC y encontré la siguiente explicación de Mark Miller en la sección de comentarios de .NET 4.0 tiene 2 caché de ensamblaje global (GAC) :

Mark Miller dijo... 28 de junio de 2010 12:13 p.m.

Gracias por la publicacion. "Cuestiones de interferencia" fue intencionalmente vaga. Al momento de escribir este artículo, los problemas aún se estaban investigando, pero estaba claro que había varios escenarios fallidos.

Por ejemplo, algunas aplicaciones usan Assemby.LoadWithPartialName para cargar la versión más alta de un ensamblado. Si la versión más alta se compiló con v4, entonces una aplicación v2 (3.0 o 3.5) no podría cargarla y la aplicación fallaría, incluso si hubiera una versión que hubiera funcionado. Originalmente, particionamos el GAC en su ubicación original, pero eso causó algunos problemas con los escenarios de actualización de Windows. Ambos involucraban código que ya se había enviado, por lo que movimos nuestro GAC (particionado por versión) a otro lugar.

Esto no debería tener ningún impacto en la mayoría de las aplicaciones y no añade ninguna carga de mantenimiento. Solo se debe acceder a ambas ubicaciones o modificarlas mediante las API de GAC nativas, que se ocupan de la partición como se esperaba. Los lugares donde esto aparece son a través de API que exponen las rutas de GAC, como GetCachePath, o examinando la ruta de mscorlib cargada en código administrado.

Vale la pena señalar que modificamos las ubicaciones de GAC cuando lanzamos la versión 2 y también cuando introdujimos la arquitectura como parte de la identidad del ensamblaje. Estos agregaron GAC_MSIL, GAC_32 y GAC_64, aunque todos todavía están en %windir%\assembly. Desafortunadamente, esa no era una opción para esta versión.

Espero que ayude a futuros lectores.

Jasl avatar Jun 29 '2010 01:06 Jasl

No tiene mucho sentido, el GAC original ya era bastante capaz de almacenar diferentes versiones de ensamblajes. Y hay pocas razones para suponer que un programa alguna vez hará referencia accidentalmente al ensamblado incorrecto, todos los ensamblados .NET 4 obtuvieron la [AssemblyVersion] mejorada a 4.0.0.0. La nueva función de lado a lado en proceso no debería cambiar esto.

Mi conjetura: ya había demasiados proyectos .NET que rompían la regla de "nunca hacer referencia a nada en el GAC directamente". Lo he visto hecho en este sitio varias veces.

Sólo hay una manera de evitar romper esos proyectos: mover el GAC. La retrocompatibilidad es sagrada en Microsoft.

Hans Passant avatar Apr 17 '2010 23:04 Hans Passant