Assembly Identity and GAC

Today, I am going to draw your attention to a very small detail in .Net Framework - Global Assembly Cache (GAC). GAC is the machine-wide store for .Net framework assemblies. Until recently, I have been under the impression that assemblies in GAC are identified based on following four characteristics:

1. Assembly Friendly Name

2. Assembly Version Number

3. Assembly Culture

4. Public Key Token

As far as I remember, I read it in the book so either I read it wrong or the book is wrong. In any case, lets clear up the understanding.

My understanding was that combination of these four attributes will always be unique in GAC. I lived under this understanding for a long while until recently when I noticed few assemblies in GAC where all above four attributes of a certain assembly were same. Shock! First because my understanding is proved to be incorrect and second it means I will have to go into detail to identify the attributes which uniquely identify assemblies in GAC and correct my understanding.

Let’s start with the discovery. I observed that when you open GAC folder (C:\Windows\assembly) in Windows Explorer there is an extra column shown, called Processor Architecture. I noticed that there is a difference in the processor architecture of the assemblies where all other four attributer were common. It led me to the conclusion that the assemblies share same friendly name, culture, version number, and public key token BUT they are targeting different processor architecture. I decided to try out this by creating a basic assembly and installing it to GAC with keeping all four attributes of the assembly same but all targeting different processor architecture - Any CPU, x86, and x64 (options in Visual Studio).

So I created a simple DLL with one class and a method with stereo code (am sure you will find code very familiar :-):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GACLearning
{
    public class Class1
    {
        public static string HelloWorld()
        {
            return "Hello World";
        }
    }
}

Built the project successfully and now it was time to generate the DLL by targeting different platforms. You can change the target processor architecture (platform) for your assembly in Visual Studio using project property page as follows (it provides three options - Any CPU, x86, and x64) :

Since we need to install assembly to GAC, it needed to be strong named. Hence, sign the assembly on signing tab under project propert page as follows:

For detailed steps to generate the key file and how to re-sign the assembly just before deployment using sn.exe tool, refer MSDN.

[Note: I removed verification of the assembly using -Vr option of sn.exe tool to make it easy for me to install assemblies to GAC]

Now I built solution three time and each time selected a different platform target under project property page and copied generated DLL to a separate folder. Three DLLs are ready which have same name, version, culture, and public key token but each target a different platform. I am ready for my test! I just dragged and dropped these assemblies to GAC folder and they all got installed to GAC happily. All three living in GAC at the same time. Shell extension does the trick under the hood by calling gacutil.exe and installs the assemblies to GAC or you can do so manually as well. Refer below screenshot of all three assemblies in GAC with only difference being in target platform:


Conclusion

There are five attributes which uniquely identify an assembly or form the identity of the assembly:

1. Assembly Friendly Name

2. Assembly Version Number

3. Assembly Culture

4. Public Key Token

5. AND Processor Architecture (Target Platform)

On a side note, if you open GAC folder directly in command prompt you will see the assembly being installed into respective folder for each platform, as shown below:

GAC 32-bit folder:

GAC 64-bit folder:

GAC MSIL folder:

Happy Coding!!

Vande Mataram!

(A salute to motherland)

P.S. In addition to blogging, I use Twitter to share tips, links, etc. My Twitter handle is: @girishjjain