2010-04-17 15 views
287

%windir%\Microsoft.NET\assembly\ è il nuovo GAC. Significa che ora dobbiamo gestire due GAC, uno per le applicazioni .NET 2.0-3.5 e l'altro per le applicazioni .NET 4.0?. NET 4.0 ha un nuovo GAC, perché?

La domanda è, perché?

+6

grazie per avermi fatto la domanda .. sono anche molto confuso quando non ho trovato gac nella sua posizione originale :) – Jasl

+2

Buona domanda ... Molte grazie. – smwikipedia

+1

+1 per la tua domanda. Ho iniziato lo sviluppo sotto NET 4.0 e sono stato confuso dal problema del "doppio" GAC. –

risposta

174

Sì poiché ci sono 2 distinte Global Assembly Cache (GAC), sarà necessario gestirle singolarmente.

In .NET Framework 4.0, il GAC ha subito alcune modifiche. Il GAC è stato diviso in due, uno per ogni CLR.

La versione CLR utilizzata per .NET Framework 2.0 e .NET Framework 3.5 è CLR 2.0. Nei due precedenti rilasci di framework non era necessario dividere GAC. Il problema di rompere le vecchie applicazioni in Net Framework 4.0.

Per evitare problemi tra CLR 2.0 e CLR 4.0, il GAC è ora suddiviso in GAC privati ​​per ogni runtime. La modifica principale è che le applicazioni CLR v2.0 non possono ora vedere gli assembly CLR v4.0 nel GAC.

Source

Perché?

Sembra che ci sia stato un cambiamento CLR in .NET 4.0 ma non in 2.0 a 3.5. La stessa cosa è accaduta con 1.1 a 2.0 CLR. Sembra che il GAC abbia la possibilità di memorizzare diverse versioni di assiemi purché provengano dallo stesso CLR. Non vogliono rompere le vecchie applicazioni.

Vedere le seguenti informazioni in MSDN about the GAC changes in 4.0.

Ad esempio, se entrambi NET 1.1 e 2.0 NET condivisi stesso GAC, quindi un'applicazione NET 1.1, caricando un assieme a questa condivisa GAC, potrebbe ottenere NET assemblee 2.0, rompendo così la NET 1.1 applicazione

La versione CLR utilizzata per entrambi .NET Framework 2.0 e .NET Framework 3.5 è CLR 2.0. Di conseguenza, lo non era necessario nelle precedenti versioni del framework per suddividere il GAC. Il problema di invecchiare (in questo caso , .NET 2.0) le applicazioni resurfaces in Net Framework 4.0 a che punto CLR 4.0 rilasciato. Quindi, per evitare problemi di interferenza tra CLR 2.0 e CLR 4.0, il GAC è ora diviso in GAC privati ​​per ciascun runtime .

Poiché il CLR viene aggiornato nelle versioni future, è possibile aspettarsi la stessa cosa. Se cambia solo la lingua, puoi utilizzare lo stesso GAC.

+16

Quel post sul blog si limita a riaffermare la scoperta dell'OP, non spiega * perché * il GAC doveva essere diviso. Non è ovvio, il GAC originale sarebbe stato abbastanza capace di tenere separati i 4.0 assembly.Hanno una nuova [AssemblyVersion] –

+1

@Hans: Forse non il motivo esatto, ma dice: "Per evitare problemi tra CLR 2.0 e CLR 4.0", anche la domanda conteneva 2 domande al suo interno. La seconda domanda è: "significa che ora dobbiamo gestire due GAC, uno per le app .NET 2.0-3.5 e l'altro per le app .NET 4.0?" –

+2

Si dovrebbe citare questo, da uno dei collegamenti: "Ad esempio, se entrambi .NET 1.1 e .NET 2.0 condividono lo stesso GAC, un'applicazione .NET 1.1 che carica un assembly da questo GAC condiviso potrebbe ottenere .NET 2.0 assembly, rompendo in tal modo l'applicazione .NET 1.1. " –

63

Non ha molto senso, il GAC originale era già abbastanza capace di memorizzare diverse versioni di assiemi. E ci sono pochi motivi per ritenere che un programma possa mai accidentalmente fare riferimento all'assembly sbagliato, tutti gli assemblati .NET 4 hanno fatto il [AssemblyVersion] urtato fino alla 4.0.0.0. La nuova funzionalità side-by-side in-process non dovrebbe cambiare questo.

La mia ipotesi: c'erano già troppi progetti .NET là fuori che hanno infranto la regola "non fare mai riferimento a nulla nella GAC ​​direttamente".L'ho visto fare più volte su questo sito.

Solo un modo per evitare di rompere quei progetti: spostare il GAC. Back-compat è sacro in Microsoft.

+3

Questa è l'unica risposta che cerca di spiegare * perché * questo è il caso. +1 –

+1

@Hans Passant: cosa intendi per "mai fare riferimento a qualcosa nella regola GAC ​​direttamente"? –

+2

@Max: ci sono due copie degli assembly .NET sulla macchina. Quelli pensati per essere assiemi di riferimento in c: \ windows \ microsoft.net e c: \ program files \ assembly di riferimento. E quelli utilizzati in fase di esecuzione, GAC @ c: \ windows \ assembly. Non sono la stessa cosa, 64 bit sarebbe un esempio. Microsoft ha fatto del suo meglio per evitare che qualcuno facesse riferimento a quelli GAC con un gestore di estensione shell. E la finestra di dialogo Aggiungi riferimento. Non efficace al 100% –

64

Volevo anche sapere perché 2 GAC e hanno trovato la seguente explanation by Mark Miller nel comments section di .NET 4.0 has 2 Global Assembly Cache (GAC):

Mark Miller ha detto ... 28 Giugno 2010 12:13

Grazie per il post. "Problemi di interferenza" era intenzionalmente vago. Al momento della stesura di , i problemi venivano ancora investigati, ma era chiaro che c'erano diversi scenari rotti.

Ad esempio, alcune applicazioni utilizzano Assemby.LoadWithPartialName per caricare la versione più alta di un assembly. Se la versione più alta è stata compilata con v4, quindi un'applicazione v2 (3.0 o 3.5) potrebbe non caricarla e l'app si bloccherebbe, anche se ci fosse una versione che avrebbe funzionato . Originariamente, abbiamo partizionato il GAC sotto la sua posizione originale , ma che ha causato alcuni problemi con gli scenari di aggiornamento di Windows . Entrambi questi codici coinvolti che aveva già spedito, così ci siamo spostati nostro (versione-partizionato GAC per un altro luogo.

Questo non dovrebbe avere alcun impatto per la maggior parte delle delle applicazioni, e non aggiunge alcuna manutenzione fardello. Entrambe le posizioni occorre accedere o modificare utilizzando le API native GAC solo, che trattano con il partizionamento come previsto. i luoghi dove ciò superficie sono attraverso API che espongono i percorsi di GAC come GetCachePath, oppure esaminando il percorso di mscorlib caricato nel codice gestito.

Vale la pena notare che abbiamo modificato GAC riprese quando abbiamo rilasciato v2 così quando abbiamo introdotto architettura come parte dell'identità assemblaggio. Quei hanno aggiunto GAC_MSIL, GAC_32 e GAC_64, sebbene tutti siano ancora sotto % windir% \ assembly. Sfortunatamente, questo non era un'opzione per questa versione.

Spero che aiuti i futuri lettori.

+3

I commenti di Miller sull'articolo collegato forniscono una vista interna sull'argomento. –