Referencing the Global Assembly Cache

5.3k views Asked by At

I have a project which needs to use NHibernate to communicate with my Oracle database.

Many projects at my workplace use NHibernate, so the NHibernate assembly was placed in the Global Assembly Cache, a tool that I do not entirely understand. From my research, I have gathered the following:

  1. The Global Assembly Cache is a central repository for dlls which are referenced by many projects. This dodges the problem of DLL Hell - when a new version of your dll is released, you update it in the cache a single time, and all .NET projects that reference it will now use the new version.
  2. You cannot add a reference to an assembly in the assembly cache. "Assemblies that have been registered in the GAC will not appear in [the Add Reference] list". You can, however, forcibly make them appear by mutilating the registry.
  3. You can easily add a reference to an assembly in the assembly cache. "simply use the Add Reference window to add a reference to an assembly you've installed in the GAC". (I'm inclined not to believe this, since I don't see any GAC assemblies in my Add Reference window).
  4. Several projects at my workplace do have references to many assemblies in the GAC. Those assemblies never appear in the "Add Reference" menu, so I know my predecessors did not use the registry mangling technique. Yet they clearly originate from the GAC - their file path is a subdirectory of C:\Windows\assembly.

Point two obviously contradicts the other three, but if it were simply false, I wouldn't have any problems referencing libraries. It definitely reflects reality in that my GAC assemblies are nowhere to be found in the "Add References" window.

I would like to know two things:

  • When would a developer ever want to use the GAC? What good is a library that can't be referenced without registry trickery?
  • What steps did my predecessors take to reference libraries in the GAC, without touching the registry?
5

There are 5 answers

2
Hans Passant On BEST ANSWER

and all .NET projects that reference it will now use the new version.

No, that's called DLL Hell. Applications reference a specific version of an assembly. You can update a DLL and update an application that uses it. And not break an old application that uses that DLL as well but didn't get recompiled. You can do that with the GAC because it can store multiple versions of a DLL. Or you can do this just as easily by keeping the DLL in the same directory as the application's EXE.

Assemblies in the GAC do not appear in the Add Reference dialog. Necessarily so, you don't know what your user has stored in her GAC. You use the Browse tab on your dev machine instead so you'll be sure that you use a specific build of the DLL.

The GAC is important to companies that need to distribute security updates. Like Microsoft. It ensures that there are no unpatched copies of the DLL floating around. Also important for [ComVisible] assemblies to solve COM's DLL Hell problem. That's about it.

0
Vinod Srivastav On

May be it's too late to answer, but i found a very simple way to do this(without a hack).

  1. Put your dll in GAC
  2. GoTo Projects --> Properties
  3. Click Reference Path and set the path of GAC
  4. and Build

Hope it helps

0
Kevin On

This appears to be how my predecessors added a reference to an assembly in the GAC:

  1. Open a project that already contains a reference to the assembly in the GAC.
  2. Select the reference and open the Properties pane.
  3. Copy the full path of the reference.
  4. In the target project, choose "Add Reference" and choose the "Browse" tab.
  5. Paste the full path into the "File Name" text box and select OK.

However, looking at the other answers, I doubt that this is a good idea. It just so happens that the GACs for the development, testing, and production environments are all identical. If the GACs weren't synced, the references probably would not remain valid.

0
Steve Rowbotham On

A "brute force" method of adding a GAC reference in your project is to directly edit the project file. Unload the project and add a Reference under the same ItemGroup element as the other references in your project, for instance:

<Reference Include="System.Management.Automation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
</Reference>

You need to be aware that there is a difference between the design-time location of assemblies in the .NET tab of the "Add Reference" dialog and the runtime resolution of those references to assemblies in the GAC. The difference between adding a reference via the .NET tab and the file browse tab is that the reference in the former case isn't marked as "Copy Local" and therefore at runtime will be looked up from the GAC. Microsoft typically places a copy of assemblies intended to be referenced from the GAC in folders under the %programfiles%\Reference Assemblies directory but these are only used at design-time.

0
Henk Holterman On

1 .... you update it in the cache a single time, and all .NET projects that reference it will now use the new version.

Not exactly. You can control whether an app uses the new or the old version. The nifty thing is both can be in the GAC at the same time.

  • What steps did my predecessors take to reference libraries in the GAC, without touching the registry?

Simply a) register it with GacUtil /i and b) Add Reference, browse to the original dll location. c) verify that the new ref has CopyLocal=false and StrongName=true