LANGUAGES: C# | VB
TECHNOLOGIES: Assemblies | Global Assembly Cache
Share DLLs Using GACUtil and SN
Use the .NET repository to access DLLs from multiple applications and escape DLL hell.
By Ken McNamee
You're probably familiar with "DLL hell" and I'm sure you've suffered from it, even if only as a product end user. In the COM world, DLLs are installed in one location on your hard drive and information about them is stored in the registry. One - and only one - version of the DLL can exist on that Windows installation. The problem here is that multiple applications might depend on the same DLL. If one of the applications installs a new version of the DLL, the other application's behavior might become unstable. Internet Explorer, for example, has been known to update system DLLs and wreak havoc with many programs - even other Microsoft applications.
You might have heard that the .NET development platform finally solves the problem of DLL hell - without a doubt, this is true. You now can simply copy all the files your application needs into a single directory structure, a process referred to as XCopy deployment. Although XCopy deployment solves some problems, it creates others because each application that uses a particular DLL must have its own identical copy. For example, if you create a new version of the DLL, you must ensure you update all the copies on the server. This is a slight maintenance headache, but it also provides you with fine-grained control over which applications will use the new version.
But maybe you don't want every application to get updated. If your intent is to install only one copy of an assembly and share it among all your applications, .NET provides a central repository for you: the Global Assembly Cache (GAC).
In this article, I'll show you the benefits of using the GAC in your development efforts. It lets you utilize some of the advantages of using registered COM components while offering the ability to store multiple versions of the same assembly. It even offers a slight performance gain over private, application-local assemblies and, under some circumstances, the GAC also can simplify assembly management. All that being said, however, you should not simply install your .NET components into the GAC by default. Doing so usually makes deploying and maintaining your applications more difficult and error-prone. Also, you can use other methods for sharing the same assembly file among multiple applications. It really comes down to your personal preference on how you want to deploy your code.
Strongly Name Your Assemblies
Once you've determined that storing your assembly in the GAC is appropriate, you need to know a few more things about the process. First of all, an assembly cannot be put into the GAC unless it has been strongly named - uniquely assigning the assembly both a public and a private key, which allows the Common Language Runtime (CLR) to know what component to load at run time. You do this because the filename itself might not be unique.
The first step to strongly naming your assembly is to create the public/private key pair that will be embedded in the assembly manifest. This is a simple process thanks to Microsoft's SN.exe command-line tool. You can create the keys with this command:
sn -k CustomerKeys.snk
Notice that you don't reference an assembly with this command. Initially, the keys aren't tied to any particular code. SN.exe merely generates the key file you need to link with your assembly to ensure it is strongly named. The name of the key file doesn't matter, but I recommend you use something descriptive.
The second step is to link the assembly with the keys SN.exe generates. You either can use the Assembly Linker tool (AL.exe), or you can add the AssemblyKeyFile attribute to your assembly's source code. Here is what that looks like in C#:
public class Customer
And in VB, the equivalent code looks like this:
Public Class Customer
During compilation, the assembly is signed using the private key, and the public key is stored in the resulting DLL's manifest portion. Figure 1 shows the public key section of the Customer.dll manifest.
Figure 1. The public key is stored in the assembly's manifest section.
Now you have an assembly ready to store in the GAC, and as with pretty much everything else in the .NET Framework, you can accomplish this in multiple ways. Using Windows Explorer, you simply drag and drop your DLL into the c:\windows\assembly folder, which has an Shfusion shell extension that understands how to accept the file and install it into the GAC automatically (see Figure 2). Note the assembly's Public Key Token property, which actually is a space-saving 64-bit hash of the much larger public key.
Figure 2. The Shfusion shell extension provides a GUI method for viewing and editing the contents of the GAC.
The Shfusion shell extension provides a quick and dirty way to add your assembly to the GAC and test it. However, you likely wouldn't want to force an end user or system administrator to do this as part of the application installation. That's where the GACUtil tool comes in. You can use it to install or uninstall an assembly either manually or using an automated installation script. Its usage is simple. Use this command-line syntax to install an assembly:
gacutil /i Customer.dll
But if you want to associate the assembly to the installation of an application, use this command:
gacutil /ir Customer.dll FILEPATH c:\Program Files\Customer\App.exe App
Uninstalling the assembly can be just as simple:
gacutil /u Customer
If multiple versions of the Customer assembly exist and you want to uninstall only one version, you will need to provide the tool with additional information so it can identify and remove the correct DLL:
gacutil /u Customer,Version=220.127.116.11,Culture=Neutral,PublicKeyToken= 5f287e49f95e68a8
Under the proper circumstances, the GAC can be a key feature of the .NET platform. The tools required to use it are simple, straightforward, and scriptable to boot. Whether you choose to use the GAC might wind up a decision of personal preference rather than actual necessity, but you should at least become familiar with its concepts.
- Global Assembly Cache (GAC): http://www.gotdotnet.com/team/clr/when_to_use_the_gac.aspx
- Easy .NET Application Deployment: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/structnetapp.asp
Ken McNamee is a senior software engineer with RelayHealth Corp., the premier provider of secure, Web-based doctor-patient communication services. Prior to this, he led a team of developers in re-architecting the Home Shopping Network's e-commerce site, HSN.com, to 100 percent ASP.NET using C#. E-mail Ken at mailto:[email protected].
Tell us what you think! Please send any comments about this article to [email protected]. Please include the article title and author.