Jaimal Chohan

The GAC

Posted by: jaimalchohan on: May 15, 2008

The GAC

Way back as part of .NET 1.1, Microsoft introduced a feature called the Global Assembly Cache, or GAC. The GAC is a virtual folder which holds references to assemblies on the hard disk.

You can view assemblies in the GAC by navigating to C:\Windows\Assembly (or whatever your root drive is) and what you should see is a unusual looking folder with lots of assemblies in it. Scroll through and should find all the .NET assemblies as well as a few for other applications you have installed.

The GAC

The GAC can only store CLR assemblies, and as you might have noticed each one has a public key, which suggests that they have been signed. Each assembly also has a version, and a culture (a blank culture defaults to neutral culture. Together with the name these 3 pieces of information make up the identity of an individual assembly.

The purpose of the GAC is to allow the sharing of assemblies across multiple applications. Imagine a scenario where you have 3 applications installed on the same server using a common Utilities assembly, if you added a reference the Utilities assembly to each project individually, then on that server you would have find 3 copies of the assembly, 1 in each bin folder. By installing the Utilities assembly it the GAC you would only need to have 1 copy.

It may sound a replacement for COM, but it’s not, the GAC is for .NET assemblies only and.NET applications are the only applications that can directly access an assembly in GAC. For legacy or non .NET applications you still have to use COM.

When you need multiple applications to use the same assembly then the GAC could be the best place to install it. You only have 1 copy per server which eases management; you only have to update 1 assembly to update all applications. All the .NET Framework assemblies are installed in GAC, that’s why you never see the .NET Framework assemblies such as the System.dll and System.Collections.dll in your applications bin folder.

Signing

To install an assembly into the GAC you first need to sign it. This can be done though Visual Studio by going to the Project properties, and clicking on the Signing tab. There you will have to check the “Sign the Assembly” checkbox and then either choose an existing string name key or let Visual Studio create a strong name key for you.

Strong Name Dialog

A strong name key consists of a private/public pair. First a hash of your assembly is created, and then the hash is encrypted with the private key part of. To distribute the assembly you provide the assembly and the public key to the receiver. The receiver decrypts the assembly using the public key and generates a hash. If the hash generated by the receiver matches the hash they decrypted then the assembly can be verified as being un-tampered with.

It may sound like the same as a Digital certificate, but it isn’t. Digital certificates are created by a certificate authority who is a trusted party and verifies that a certificate you attach to an assembly belongs to you. With a strong names there’s nobody to provide that facility and therefore somebody could replace your key with their own, there’s no mechanism to verify who the key belongs to. Knowing this if you plan to distribute an assembly outside of your department or company then you should obtain a digital certificate from a trusted certificate authority.

Another method to create a strong name key is to use the Visual Studio Command Prompt and run the following

sn -k

After you have assigned a key to your project the assembly will be signed when built.

Deployment

Once you have built your assembly you can install it into the GAC by drag-dropping it into the C:\Windows\Assemby folder or by running the following command in the Visual Studio Command Prompt.

gacutil -i

You can also create a setup project to deploy your assembly via an installer which is a much cleaner method for deployment.

GAC Setup Project

Once deployed you can use your assembly like any other .NET assembly by adding a reference to it into your .config file:

<assemblies>
   <add assembly="<assemblyName>, Version=<version>, Culture=<culture>, PublicKeyToken=<publicKey>"/>
</assemblies>

“Hold on”, i hear you say, who adds references manually to their .config file like above? normally you’d right click on your references folder in Visual Studio and add it from there. Unfortunately the Add Reference dialog is not driven from the GAC, its driven from the registry, so you’ll have to add a registry key for this level of functionality; another reason to use a setup project for deployment.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\\[Default String Key with value =

Version Management

When you do have a shared assembly, you want to be able to version it, so that in the future you can create a new version and not break the existing one. Make sure you have a versioning strategy in place, it doesn’t have t be complex, you don’t have to make use of the minor digits, a simple X.0.0.0 version will do.

When you deploy your new version it will be a completely separate install so make sure you’ve archived your previous version, and the source files to go with it in case a bug crops up in the future that you need to fix. Your new assembly will not affect the old assembly as long as the version numbers are different.

Once you’ve deployed the new version you’ll do 1 of three things.

1. Use your new version for new applications and let applications using the old version carry on using the old version.

2. Force some applications on a server to use the new version: In this case you have to add a binding redirect element ton your applications .config file.

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name="<assemblyName>"
                              publicKeyToken="<publicKey>"
                              culture="<culture>" />
            <bindingRedirect oldVersion="1.0.0.0"
                             newVersion="2.0.0.0"/>
         </dependentAssembly>
      </assemblyBinding>
   </runtime>
</configuration>

3. Force all applications on a server to use the new version (only likely to do this if a version is backwards compatible): You’ll have configure this using the Microsoft .NET Framework Configuration Tool via Control Panel > Administration Tools.

Expand the My Computer node, expand the Configured Assemblies Node, click on Configure and Assembly and then choose an Assembly to configure. This will add the Assembly to the list of Configured Assemblies and from here you can set the binding policy.

Binding Policy Dialog

As you can see, the GAC is a very handy feature and easy to use, if you need to deploy an assembly which will be shared by multiple applications, then the GAC is the way to go.

Leave a Reply