This multi-part article answers common questions about assemblies, the basic building blocks of .NET applications. This Part 4 covers shared assemblies and the Global Assembly Cache.
Where are shared assemblies stored?
A shared assembly is used by multiple applications. You can store shared assemblies pretty much anywhere. However, the challenge is to ensure that all dependent applications can find the shared assembly. The recommended way to ensure this is to store shared assemblies in the Global Assembly Cache.
What is the Global Assembly Cache (GAC)?
The Global Assembly Cache is a system folder (typically C:Windowsassembly) that contains .NET shared assemblies. Companies that wish to share assemblies with others or even just among their own applications typically store these shared assemblies in the GAC. All of the .NET framework libraries are stored in the GAC.
Why should I store my shared assemblies in the GAC?
You should install assemblies in the GAC only when necessary. As a general guideline, assemblies should be kept private and stored in the application’s folder unless you explicitly need to share them. There are some benefits to storing shared assemblies in the GAC:
Global Location
The GAC is the known standard location for .NET shared assemblies. When an application attempts to load an assembly, the GAC is one of the first places it looks. If there’s any chance that an application outside your control may someday require access to your shared assembly, you should install your assembly in the GAC so the application is sure to find it.
Security
The GAC is a system folder typically protected by administrator rights. Once an assembly is installed in the GAC, it cannot be easily modified. Also, assemblies stored in the GAC must be signed with a cryptographic key. These protections make it difficult to spoof your assembly, in other words, replace or inject your assembly with a virus or malicious code.
Version Management
.NET allows multiple versions of the same assembly to reside in the GAC so that each application can find and use the version of your assembly to which it was compiled. This helps avoid DLL Hell, where applications that may be compiled to different versions of your assembly could potentially break because they are all forced to use a single version of your assembly.
Faster Loading
The system verifies assemblies when they are first installed in the GAC, eliminating the need to verify an assembly each time it is loaded from the GAC. This can improve the startup speed of your application if you load many shared assemblies.
Why would I avoid the GAC?
The GAC should contain “global” shared assemblies only, so there are many instances when you would NOT install an assembly in the GAC:
- The assembly is private to your application and not to be shared with other applications.
- You want to use XCOPY or FTP copy to install a .NET application to a single folder. This eliminates the need to access the Registry and GAC and does not require administrator rights.
- The assembly is not strong-named or you do not want tight version control.
- COM interop and unmanaged code do not require the GAC.
How do I see assemblies installed in the GAC?
The .NET Framework includes an Assembly Cache Viewer. Open Windows Explorer, enter %windir%assembly in the address bar, and all global assemblies will appear in a special view that shows the assembly name, version, culture, public key token, and processor architecture.
Can I install multiple versions of the same assembly in the GAC?
Yes. Normally you would not be able to have two files with the same name in a Windows folder, but the GAC is a special folder that stores its contents by strong name. Hence, two assemblies with the same name but different versions or cultures may coexist in the GAC.
How do I add/remove assemblies from the GAC?
Assemblies added to the GAC must be signed with a strong name. There are multiple ways to add/remove assemblies from the GAC:
Windows Installer
The preferred way to add/remove assemblies from the GAC is with Microsoft Windows Installer 2.0. Visual Studio includes a limited version of Windows Installer, and most major setup programs such as InstallShield also use Windows Installer. There are benefits to using Windows Installer:
- Windows Installer provides a simple interface for developers to add/remove shared assemblies in the GAC and can handle private assemblies as well.
- Installer provides a familiar interface and setup experience for the user.
- Installer can also install application shortcuts and supporting files such as ReadMe and license agreements and can run other installation programs and scripts.
- Installer registers and tracks references to assemblies installed in the GAC to determine which assemblies are still required.
- Installer can repair and patch assemblies and rollback unsuccessful installations.
- Installer can install assemblies on-demand as they are needed by applications.
GAC Utility
The .NET developer’s kit includes a command line utility GACutil.exe to interact with the GAC. This utility is intended for use in a development environment only and should not be used to install assemblies on a client PC because:
- The GACutil license agreement states that it is not freely distributable.
- GACutil is part of the .NET SDK, which may not be installed on many target PCs.
- GACutil lacks many important features found in Windows Installer such as assembly repair and rollback.
Assembly Cache Viewer
Using the Assembly Cache Viewer shown above, you can drag & drop assemblies from any folder into the GAC and also delete assemblies installed in the GAC.
.NET Framework Configuration Administrative Tool
To access the .NET Framework Configuration Tool:
- Click Start > Control Panel.
- Double-click on Administrative Tools.
- Double-click on Microsoft .NET Framework 2.0 Configuration.
- Ensure My Computer is selected in the tree.
- In the Tasks group, click the Manage the Assembly Cache link.
- Two links appear, enabling you to view and add assemblies in the GAC.
How do I access the GAC programmatically?
You can access the GAC from code with the fusion.dll library. Here is an excellent C# wrapper for the GAC.
You are strongly advised NOT to access the GAC from code unless you are creating an administrative or setup tool. The Fusion APIs expose your application to the inner workings of assembly binding and may cause your application to fail on future .NET versions.
How do I add my shared assembly to the Visual Studio “Add Reference” dialog?
If you add an assembly to the GAC, it will NOT automatically appear in the Visual Studio “Add Reference” dialog; instead you must add your assembly manually.
How do I move the GAC?
When installing .NET, you cannot configure the GAC location, however you can move the GAC after it is installed. See this article and scroll down to “Relocating the GAC.”
Links
- Demystifying the GAC
- GAC Phobia
- Avoid the GAC
- GAC Not Completely Useless
- To GAC or Not GAC? That is the Question
.NET Assembly FAQ – Part 1
.NET Assembly FAQ – Part 2 – Attributes
.NET Assembly FAQ – Part 3 – Strong Names and Signing
.NET Assembly FAQ – Part 5 – coming soon
what is the application on global assembly?
Hi Rekha, I don’t understand your question. Please elaborate.
hello sir,
I found your article really very informative. It has cleared my many GAC related doubts. But still i have some more doubts…
Whenever we comply a .Net application, CLR converts the source code into IL. Moreover it creates an assembly which contains the metadata and the IL (please correct me if i am wrong).
My doubt is : where exactly is this assembly created?
Can we view the files and dlls in that assembly? Does CLR generates new dlls each time we compile our application?
Thanks
Falguni
Yes, a new assembly is created each time you compile. Note that an assembly can be a DLL or EXE.
Use the MSIL disassembler (Ildasm.exe) to view Microsoft intermediate language (MSIL) information in an assembly, including the assembly’s attributes, as well as references to other modules and assemblies.
http://msdn.microsoft.com/en-us/library/ceats605.aspx
If I have 2 different Version of same Assembly then How to access both (pld and New) Version of the Same Assembly.
Please Provide Me Help.
If both versions of your assembly are in the GAC, then your application will automatically load the correct version assembly against which it was originally compiled.
Or, you can manually load an assembly at runtime with the Assembly.Load() method.
Format of MSIL.?
Hi Timm,
Assemblies Faq’s are Mind Blowing .Thank You.
Here I have a question .
If multple versions of assembly are created.How to refer a older and newer version assembly in my application.
Regards
Sridhar
Re: If multple versions of assembly are created. How to refer a older and newer version assembly in my application.
Your application will target whichever assembly you build it with. You can choose which version to build to when you Add Reference to the assembly in your Visual Studio project. If you add a reference to the old assembly, that’s the version your application will target when it runs.
Can you please let me know what are the possible ways available to identify which version of assembly does application uses or to ensure whether the application is using prompt version of assembly in case of multiple version of assemblies in production environment, other than checking web.config file.
For example : Suppose Application A has to use older version of assembly 1.0.0.0 and Application B has to use newer version of assembly 1.0.1.0.Wants to ensure Application A is still using version 1.0.0.0 even after newer version added to GAC.
Why only shared assemblies be added to GAC ? Why one should not add my private assembly into GAC
b’coz assemblies from GAC will load faster
Can some one clarify my doubt
Re: Why only shared assemblies be added to GAC ? Why one should not add my private assembly into GAC
b’coz assemblies from GAC will load faster
Installing assemblies to the GAC requires more effort and has stricter requirements (cannot use XCOPY, must be signed, etc.) But if you want to install your private assembly into the GAC, that’s fine too.
Question:
Can I use two different versions of the same assembly in a single application? if yes then how?
Any thought would be appreciated.
Thanks,
[…] .Net Assembly FAQ – part 4 – Global Assembly Cache […]
Hello,Terrific blogging dude! i am just Tired of using RSS feeds and do you use twitter?so i can follow you there:D.
PS:Have you thought to be putting video to your blog to keep the readers more enjoyed?I think it works.Yours, Keitha Hegdahl
@Keitha Hegdahl: Great idea, C# 411 is now on Twitter!
https://twitter.com/CSharp411
I could not have said it better myself!
hi timm, hope u r doing well….so here’s my question-
i’m new to .net environment, however i’ve tried successfuly programming by building class library dlls and referencing them from windows application.they ran fine.I deleted those dlls along with their folder and then also ran well.I created new dlls,strong named them and installed them in GAC.Then i implemented those assemblies in my new windows application.They ran well again.I deleted again those dlls(Shift+Delete) and then again they ran well.And i never kept my dlls in any instance, into my project folders. Then what r the benefits of installing dlls in GAC? Another question is, after succesfully installing dlls/assemblies into GAC, again i need to make references to them by browsing the location to implement in application project.Cant i simply import them as i do incase of system.data or system.windows.forms without making explicite reference?
@john: It’s a little tough to follow your question, but I think I can answer the last one. Once you add an assembly to the GAC, it should appear in the “.NET” tab of the Visual Studio “Add Reference” dialog. Select it there, and add a reference to your project. Whereas before you added it to the GAC, you had to find your assembly in the “Browse” tab.
hi timm, thank u a lot…u r really a nice n helpful guy, god bless u. I followd ur answer n my 2nd question was perfectly answered. thanx again. but my 1st question was–i made 2 different projects but ran 4times in different circumstaces and in any case i never kept my dlls or assemblies inside my project folders.for 1st project i made reference to ‘mylib.dll’ wich is in,say ‘myfolder’, and not in my proj folder.and i cud run it perfectly. then i deleted ‘myfolder'(SHIFT+Del) along with ‘mylib.dll’ and wanted 2 see what difference it makes.But again my project ran perfectly even though ‘mylib.dll’ had been deleted. In case of 2nd project, i made ‘nextlib.dll’ in say ‘next’ folder. then i strong named it and installed in GAC. then i made a reference to ‘nextlib.dll’ from my windows_application project and ran it. it was perfect. 2 see the difference i again deleted ‘next’ folder along with it’s ‘nextlib.dll'(SHIFT+Del).And then ran it, but this time also it ran perfectly though i already had deleted the physical ‘nextlib.dll’. my question is– when i can run both the projects similerly (before and after deleting corresponding dlls) without having the referenced dll file present in computer, then what extra benefit do i enjoy while installing dlls into GAC? in other words- what r the differences @ runtime between having dlls installed into GAC and not Having dlls into GAC?
Hi Timm, hope you r doing just gr8.Here i’m with another very important question….i’ve installed a dll file namely “msgclass.dll’ into GAC successfully after strong naming it. even it’s showing in C:Windowsassembly folder. But when i’m trying to implement it in my new windows_application project, by following “right click on project name–>add reference” –>searching under .net tab, but it’s not showing there. i can add that reference by browsing it, but why should i do that when i’ve already installed it in GAC without any error and it’s there in windows/assembly directory? what might go wrong with it? I’m just waiting for ur answers eagerly. Your answers so far helped me a lot to develop and grab the concept.Please Timm, reply as soon u notice my questions. Have a nice day, God bless u.
@john: See this article on how to add GAC assemblies to the Add Reference dialog:
https://www.csharp411.com/adding-assemblies-to-the-visual-studio-add-reference-dialog/
And this article explains why you’d want to use the GAC:
https://www.csharp411.com/net-assembly-faq-part-4-global-assembly-cache/
Cheers!
Hi timm, actually i’m running short of words 2 thank u, u’ve been an angel 2 me.ur guidence not only helped me acheive the task but cleared my all doubts, it provided me with much awaited logical guidence.both of my questions are answered correctly and appropriately.it was short but to the point and finally i tried it and it’s been a successful try. thanx again. whoever u r, wherever u r, hope God ‘ll always by ur side.stay happy, take care. I’m from india n a software programmer, done many vb application projects but now trying 2 switch to vb.net, n ur support helped me 2 a great extent towards become a good vb.net programmer. thanx again, u r definitely a helpful n good human being. May be someday i’ll annoy u again with a much complexed question.hahaha…..but never change urself, i’ll never mind 2 meet u someday, good man. byeee for now…
Hi Timm, hope u r just doing well n everything is going fine for.Again i’ve come up with a question. Say i’ve built a vb.net project and Used crystal report for reports and sql-server 2005 as backend. now how do i make the exe or installer so that when i’ll install my project’s exe in client’s machine, i don’t need to install sql-server and crystal report there explicitly? it’ll automatically install sql-server/crystal report in client’s machine while installing my vb.net installer.In otrher words, how will my exe incorporate sql-server/crystal report so that installing my vb.net exe in client’s machine ‘ll automatically install sql-server/crystal report as well? u’ve already helped me a lot in a ‘to the point’ manner and it gets me a lot of faith in your knowladge n skills.please help me inthis issue as well, thanx in advance, good man, god almighty bless u, i can assure u this little that whatever u’ve taught me so far, i’ve learnt them appropriately without any confusion. Thanx again to spend your valuable time on my blog.Byeee for now, Have a nice time ahead.
If you are developing several services to be used via the GAC, can you just copy the same .pfx file and use in all of them, or is it better practice to have separate ones for each applicaiton? Also, what would happen if the original .pfx file disappears?
same assembly r stored in gac using gac what is another solution.b’coz one interviewer was asking me that.can anybody tell me.plz send me reply to my mail.
Great article — much better than what is on MSDN.
One thing you didn’t quite address — what about in an IIS production server environment? We want to install some third-party DLLs (which don’t really change, unlike our app’s DLLs) into the GAC for memory benefits (otherwise, we’d have one copy of each third-party DLL per site on the server, and we have 150 sites per server).
In your article, you refer to using an Installer but in this case it’s a third-party component and their installer would try to install and set it up in Visual Studio, which of course isn’t on a production IIS server. Likewise, gacutil is part of Visual Studio or the Windows SDK, neither of which we really want to install on a production server. What are people doing to install DLLs on production servers?
What is satellite assembly?How and what is the use of it?
What is satellite assembly?How and what is the use of it?