When and when-not to install into the GAC?
When should you install into the GAC and when should you not? (I am referring, really, to installing on a client's machine when they have purchased our product(s)).
I have an assembly that is only going to be used with my one application (GAC or no-GAC)?
I have an assembly that all my applications share (GAC or no-GAC)?
All my applications may use different versions of my assembly (GAC or no-GAC)?
These are three scenarios... but I am sure there are more. I'm not necessarily looking an answer to only these three questions.
Similar question: What are the advantages and disadvantages of using the GAC?
General MS guidelines
- no
- no
- no
GAC is really a repository for Microsoft common .NET libraries. Yes, they let developers use it too, but as a rule of thumb, if you don't need GAC, don't use it. keep things simple and local if it doesn't hurt.
I would consider GAC only for performance reasons, for example if you have some huge assemblies, try to place them into GAC and NGEN them. It should significantly increase performance. Microsoft does it for all standard .NET framework assemblies during installation (now you know why that installation takes so long). Paint.NET does it as well (to improve startup time of their app). However most of us don't work on huge frameworks or photoshop competitors, so most of the time, performance gains from having assembly in GAC are minimal. Not worth giving up simple x-copy deployment.
Some developers might use GAC to make sure that users with insufficient privileges can't delete or modify their assemblies.
For others it might be for versioning reasons but here you should really reconsider. I'm not going to repeat what has been already said, you can read here why.
And don't forget that once you want to deploy into GAC, your installer will need administrator privileges, you can pretty much forget click-once deployment, etc...
Useful cases for GAC:
- COM-callable code - i.e. you want some non-.NET code to be able to access you without messing with dlls etc
- Serviced Components (COM+)
- If you are writing code that is so common it is actually meaningful to use GAC - primarily .NET framework components etc
- If you want to use NGEN to pre-JIT the code
Other than that, I tend to avoid the GAC like the plague. It is far easier to just deploy the necessary dlls with your app via robocopy
etc; this gives isolation and easy deployment.
If you are installing asp.net web applications and you are the owner and have complete control over the machine, then in some cases it could make sense putting your assemblies, which you plan to share across sites/web instances in the global assembly cache.
You could dramatically improve the initial loading time and memory usage of the application on servers which have many multiple instances of the same ASP.NET applications if you put the assemblies in the GAC. At least I saw this on our servers with dozens of installations.
If you're shipping a reusable library consisting of multiple assemblies, but only few of them form a facade, you can consider installing the assemblies into GAC, if the package is installed to developer's PCs.
Imagine, you ship 6 assemblies, and only one of these 6 assemblies contains a facade - i.e. other 5 are used only by the facade itself. You ship:
- MyProduct.Facade.dll - that's the only component intended to be used by developers
- MyProduct.Core.dll - used by MyProduct.Facade.dll, but not intended to be used by developers
- MyProduct.Component1.dll - the same
- MyProduct.Component2.dll - the same
- ThirdParty.Lib1.dll - third-party library used by MyProduct.Component1.dll
- ThirdParty.Lib2.dll - the same
- etc.
Developers using your project would like to reference just MyProduct.Facade.dll in their own projects. But when their project runs, it must be able to load all the assemblies it references - recursively. How this can be achieved? In general, they must be available either in Bin folder, on in GAC:
- You may ask the developers to locate your installation folder and add references to all N assemblies you put there. This will ensure they'll be copied into Bin folder to be available in runtime.
- You may install VS.NET project template already containing these 6 references. A bit complex, since you should inject the actual path to your assemblies into this template before its installation. This can be done only by installer, since this path depends on installation path.
- You may ask developers to create a special post-build step in .csproj / .vbproj file copying the necessary dependencies to Bin folder. The same disadvantages.
- Finally, you may install all your assemblies into GAC. In this case developers must add the reference just to MyProduct.Facade.dll from their project. Everything else will be available in runtime anyway.
Note: last option doesn't make you to do the same while shipping the project to production PCs. You can either ship all the assemblies within Bin folder, or install them into GAC - all depends all your wish.
So the solution described shows the advantage of putting third-party assemblies into GAC during the development. It doesn't related to production.
As you may find, installation into GAC is mainly intended to solve the problem of location of required assemblies (dependencies). If an assembly is installed into GAC, you may consider it exists "nearby" any application. It's like adding path to .exe to your PATH variable, but in "managed way". - of course, this is rather simplified description ;)
Here's the link from Chris Sells called "Avoid the GAC"
https://sellsbrothers.com/12503
The explanation is pretty long, but in short, the two cases he identifies are
Fixing critical bugs without touching the affected apps (and without breaking anything!)
Sharing types at run-time between assemblies deployed separately
Note: There is a very long discussion thread at the end of Chris's the post, very nice list of comments.