When should I deploy my assemblies into the GAC?

I would like to know practically what kind of Assemblies should I deploy in GAC.

Case 1: If in my Solution multiple project uses log4net.dll then should it be deployed in GAC?

Case 2: If I have multiple application deployed in a machine each using log4net.dll is this the reason enough to deploy log4net.dll into GAC?


Solution 1:

Question: When should I deploy my assemblies into the GAC?

Answer: Never

Actual, honest, Real Answer: Hardly Ever

Discussion

Only drop things into the GAC when multiple apps on the machine will use the assembly, and when the assembly is foundational (likely to be used by multiple apps), when it is signed, and when you expect to almost never update that assembly. Maybe add into that, when having multiple independent versions of a DLL deployed with each application would actually be harmful.

An example of the latter is: suppose you have 2 independent applications, independently developed and independently deployed. Nevertheless, there is a possibbility that they will inter-communicate. They will exchange ... something... over .NET Remoting on the local machine. If you have a single assembly in the GAC, these apps are assured that the inter-communication will just work. If, however, they each have a separate version of an assembly, they may not be able to exchange objects. This is such a rare occurrence that you probably don't need it. If you're not sure, then you don't need it.


The base GAC scenario is the .NET Base Class Library. These assemblies are shipped by Microsoft. They are authoritative. They are foundational. and signed. They rarely change. All apps should use the same copies of those DLLs. Therefore, they belong in the GAC.

In contrast, your application DLLs are not from Microsoft, they are not foundational, and probably not signed. They change more often, and there are only few apps (maybe only one!) that use each DLL. No GAC.


I could imagine a hardware device, let's say a digital camera, that installs a .NET assembly to allow programmability. That's a scenario where the assembly might fit well into the GAC. It allows arbitrary .NET apps to access the digital camera programmatically.


Your log4net example is not, in my opinion, enough to justify putting the assembly in the GAC. Imagine the scenario where one of the apps gets an update, and as part of the update it uses a new version of log4net. Now what? Should the new log4net assembly be placed into the GAC? Probably not.

The whole idea of sharing DLLs across applications was rooted in the premise that memory and disk storage was scarce. Once upon a time, that was true. It is not true, any longer. When in doubt, don't use the GAC.

Solution 2:

the log4net.dll has a size of 95KB. even if you deploy it a 100 times it wouldn't really matter with todays harddisks. i try to avoid the GAC wherever possible for several reasons:

  • it makes deployment harder, you have to tell the installer what to put into the GAC. i like the possibility to create simple xcopy setups (copy a dir to install, delete it to uninstall). because that's simple - but it doesn't work so well as soon as you have to put things into the GAC.
  • you have to sign your assemblies. only to get them into the GAC....
  • as soon as a developer references something from the GAC in his visual studio project, the reference will be lost when another developer opens the solution on his pc. he'll first have to get the required assemblies into the GAC before he can successfully open and compile the solution. that's a real PITA. i want to be able to checkout, compile and run without errors.

Solution 3:

The only sort of assembly you should consider putting into the GAC is a mature and stable assembly. In the case of log4net, if you're happy that the version you have is stable, mature, and you're not likely to change that version anytime soon, feel free to put it in the GAC.

Do not attempt to place libraries in the GAC that are likely to change, especially if you are developing them in-house and there is still scope for further improvement. Deploy them as private assemblies instead.

I have seen people evangelize the wonder of shared code. They say things like "ah, we'll improve 20 applications at the same time with this code change". Problem is, you can also destroy 20 apps at the same time if you get it wrong. I have seen people say "I have just launched site X. Can you please check sites A-W to make sure they still work?".

Private assemblies can be a pain, but the problems that you might face are constrained to the specific application that they are deployed against. If you are not 100% sure that an assembly isn't stable and mature, don't put it in the GAC.

Trust me, you'll sleep better.