Sunday 7 November 2010

When to install assemblies into the GAC

I have recently been working on an established project which makes use of the Global Assembly Cache (GAC) for most of the assemblies in the application. I have found the experience quite frustrating because keeping the assemblies in sync with the code has been tedious. But I realised I wasn’t really sure if using the GAC was a good idea or not so I’ve done a bit of research.

“Each computer where the common language runtime is installed has a machine-wide code cache called the global assembly cache. The global assembly cache stores assemblies specifically designated to be shared by several applications on the computer.

You should share assemblies by installing them into the global assembly cache only when you need to. As a general guideline, keep assembly dependencies private, and locate assemblies in the application directory unless sharing an assembly is explicitly required. In addition, it is not necessary to install assemblies into the global assembly cache to make them accessible to COM interop or unmanaged code.” *

OK, so there’s the first point. Microsoft suggest, “You should share assemblies by installing them into the global assembly cache only when you need to”.

The GAC is useful for deploying assemblies to be shared by a set of applications but I like the possibility of XCOPY deployments. However, deploying an assembly to the GAC is reported to improve its load performance compared to assemblies not located in the GAC. In addition strongly named assemblies are reported to load faster from the GAC because they are verified at the time they are installed rather than at runtime. In effect the .NET framework skips runtime verification for assemblies loaded from the GAC.

Back to Microsoft:

“There are several reasons why you might want to install an assembly into the global assembly cache:

  • Shared location.

Assemblies that should be used by applications can be put in the global assembly cache. For example, if all applications should use an assembly located in the global assembly cache, a version policy statement can be added to the Machine.config file that redirects references to the assembly.

  • File security.

Administrators often protect the systemroot directory using an Access Control List (ACL) to control write and execute access. Because the global assembly cache is installed in the systemroot directory, it inherits that directory's ACL. It is recommended that only users with Administrator privileges be allowed to delete files from the global assembly cache.

  • Side-by-side versioning.

Multiple copies of assemblies with the same name but different version information can be maintained in the global assembly cache.

  • Additional search location.

The common language runtime checks the global assembly cache for an assembly that matches the assembly request before probing or using the codebase information in a configuration file.” **

I find reasons such as side-by-side versioning quite compelling. I for one have worked on projects where various open source tools refer to different versions of other libraries. Getting all of the assemblies to live together in a single application directory can be a challenge. However, it must be noted that earlier in the article quoted above states:

“You should share assemblies by installing them into the global assembly cache only when necessary. As a general guideline, keep assembly dependencies private and locate assemblies in the application directory unless sharing an assembly is explicitly required.” **

* Global Assembly Cache
** Working with Assemblies and the Global Assembly Cache

Sunday 7 November 2010