.NET 4.0 has 2 Global Assembly Cache (GAC)




While reading an article on Understanding The CLR Binder, I found out that .NET 4.0 has 2 distinct GAC’s (Global Assembly Cache). In previous .NET versions, when I installed a .NET assembly into the GAC (using gacutil.exe), I could find it in the ‘C:\Windows\assembly’ path. With .NET 4.0, GAC is now located in the 'C:\Windows\Microsoft.NET\assembly’ path.

Note that previous versions of .NET continue using the same ‘C:\Windows\assembly’ path. The article says:

In .NET Framework 4.0, the GAC went through a few changes. The concept of placing assemblies into a global directory began in CLR v1.1. In case of .NET Framework 1.1 (which had CLR v1.1) and .NET Framework 2.0 (which had CLR 2.0), the GAC was split into two, one for each CLR. This avoided the leaking of assemblies across CLR versions. 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.”
Interference Issues? Hmm..Interesting although I am still pondering over the reason! So that means, the GAC split reasoning in a .NET 4.0 scenario could be re-quoted as “If both .NET 2.0 and .NET 4.0 shared the same GAC, then a .NET 2.0 application, loading an assembly from this shared GAC, could get .NET 4.0 assemblies, thereby breaking the .NET 2.0 application”

I am eager to try out a scenario to see it myself. The baseline is, you now have 2 GAC’s in .NET 4.0 and you will now have to manage each of them individually!

Any other reasons you can think of the .NET 4.0 GAC split? Feel free to share them in the comments section.


Will you give this article a +1 ? Thanks in advance




About The Author

Suprotim Agarwal, ASP.NET Architecture MVP works as an Architect Consultant and provides consultancy on how to design and develop Web applications.

Suprotim is also the founder and primary contributor to DevCurry, DotNetCurry and SQLServerCurry. He has also written an EBook 51 Recipes using jQuery with ASP.NET Controls.

Follow him on twitter @suprotimagarwal

comments

6 Responses to ".NET 4.0 has 2 Global Assembly Cache (GAC)"
  1. Scott Brickey said...
    June 28, 2010 at 7:22 AM

    I'm not reading much difference in GAC behavior.

    if you actually look into the file system behind the GAC (which requires either a command prompt to understand the folder structure, or drive mappings), Microsoft has always had a folder structure as:
    assembly\arch\assembly\version

    where arch may be x86, x64, or MSIL.

    The multiple versions allows me to publish 3 versions of the same assembly concurrently. This allows program A to use v1, program B to use v2, and program C to use v3.

    This solves the DLL Hell problem which used to exist, in which case they would all be forced to use the same version, which inevitably would include incompatibilities.

    So you ask why 3.0 and 3.5 used the 2.0 CLR? because it wasn't changing anything, it was building. DotNet 2 *REPLACED* a ton of functionality from 1.0/1.1 (anyone who dealt w/ 1.1 remembers the pains). 3.0's WCF/WPF/WWF weren't replacing anything from 1.0/1.1 or 2.0, and 3.5's LINQ/etc weren't replacing anything from 1.1/2.0/3.0.

  2. Mark Miller said...
    June 28, 2010 at 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.

  3. Atul Gupta said...
    June 28, 2010 at 8:54 PM

    This is interesting, though am not clear why say a %windir%\assembly\v4 option didn't work?

    Also interestingly the path for .NET 4 GAC isn't integrated with the shell extension (ShFusion.dll) and hence doesn't provides the default look of what is seen in %windir%\assembly

  4. For a roof on head said...
    June 29, 2010 at 12:09 AM

    I guess this was the whole side by side execution base requirement - so not major deal as native gac apis access it.

  5. Anonymous said...
    February 3, 2011 at 2:19 AM

    2 Gac's? wow I never knew that! We are upgrading out .net 2.0 app to 4.0 and I will keep this point in mind. Thanks for this post!

    - Greetings from Andrey of bulgaria

  6. Lucian Schultz said...
    June 20, 2013 at 5:53 AM

    Your articles it’s very useful for me a lot about the.NET 4.0 has 2 Global Assembly Cache (GAC), and I am completely satisfied with your Blog. All comments and articles are very useful and very good. Your blog is very attention-grabbing. This article is very informative. Thank you for sharing this article.

 

Copyright © 2009-2014 All Rights Reserved for DevCurry.com by Suprotim Agarwal | Terms and Conditions