.NET 4.0 has a new GAC, why?

.Net.Net 4.0Gac

.Net Problem Overview


%windir%\Microsoft.NET\assembly\ is the new GAC. Does it mean now we have to manage two GACs, one for .NET 2.0-3.5 applications and the other for .NET 4.0 applications?

The question is, why?

.Net Solutions


Solution 1 - .Net

Yes since there are 2 distinct Global Assembly Cache (GAC), you will have to manage each of them individually.

> In .NET Framework 4.0, the GAC went through a few changes. The GAC was split into two, one for each CLR. > >
>The CLR version used for both .NET Framework 2.0 and .NET Framework 3.5 is CLR 2.0. There was no need in the previous two framework releases to split GAC. The problem of breaking older applications in Net Framework 4.0. > >To avoid issues between CLR 2.0 and CLR 4.0 , the GAC is now split into private GAC’s for each runtime.The main change is that CLR v2.0 applications now cannot see CLR v4.0 assemblies in the GAC.

Source

Why?

It seems to be because there was a CLR change in .NET 4.0 but not in 2.0 to 3.5. The same thing happened with 1.1 to 2.0 CLR. It seems that the GAC has the ability to store different versions of assemblies as long as they are from the same CLR. They do not want to break old applications.

See the following information in MSDN about the GAC changes in 4.0.

>For example, if both .NET 1.1 and .NET 2.0 shared the same GAC, then a .NET 1.1 application, loading an assembly from this shared GAC, could get .NET 2.0 assemblies, thereby breaking the .NET 1.1 application >
> The CLR version used for both .NET > Framework 2.0 and .NET Framework 3.5 > is CLR 2.0. As a result of this, there > was no need in the previous two > framework releases to split the GAC. > The problem of breaking older (in this > case, .NET 2.0) applications > resurfaces in Net Framework 4.0 at > which point CLR 4.0 released. Hence, > to avoid interference issues between > CLR 2.0 and CLR 4.0, the GAC is now > split into private GACs for each > runtime.

As the CLR is updated in future versions you can expect the same thing. If only the language changes then you can use the same GAC.

Solution 2 - .Net

I also wanted to know why 2 GAC and found the following explanation by Mark Miller in the comments section of .NET 4.0 has 2 Global Assembly Cache (GAC):

> Mark Miller said... > June 28, 2010 12:13 PM > > Thanks for > the post. "Interference issues" was > intentionally vague. At the time of > writing, the issues were still being > investigated, but it was clear there > were several broken scenarios. > > For instance, some applications use > Assemby.LoadWithPartialName to load > the highest version of an assembly. If > the highest version was compiled with > v4, then a v2 (3.0 or 3.5) app could > not load it, and the app would crash, > even if there were a version that > would have worked. Originally, we > partitioned the GAC under it's > original location, but that caused > some problems with windows upgrade > scenarios. Both of these involved code > that had already shipped, so we moved > our (version-partitioned GAC to > another place. > > This shouldn't have any impact to most > applications, and doesn't add any > maintenance burden. Both locations > should only be accessed or modified > using the native GAC APIs, which deal > with the partitioning as expected. The > places where this does surface are > through APIs that expose the paths of > the GAC such as GetCachePath, or > examining the path of mscorlib loaded > into managed code. > > It's worth noting that we modified GAC > locations when we released v2 as well > when we introduced architecture as > part of the assembly identity. Those > added GAC_MSIL, GAC_32, and GAC_64, > although all still under > %windir%\assembly. Unfortunately, that > wasn't an option for this release.

Hope it helps future readers.

Solution 3 - .Net

It doesn't make a lot of sense, the original GAC was already quite capable of storing different versions of assemblies. And there's little reason to assume a program will ever accidentally reference the wrong assembly, all the .NET 4 assemblies got the [AssemblyVersion] bumped up to 4.0.0.0. The new in-process side-by-side feature should not change this.

My guess: there were already too many .NET projects out there that broke the "never reference anything in the GAC directly" rule. I've seen it done on this site several times.

Only one way to avoid breaking those projects: move the GAC. Back-compat is sacred at Microsoft.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMax ToroView Question on Stackoverflow
Solution 1 - .NetBrian R. BondyView Answer on Stackoverflow
Solution 2 - .NetJaslView Answer on Stackoverflow
Solution 3 - .NetHans PassantView Answer on Stackoverflow