How to prevent a .NET application from loading/referencing an assembly from the GAC?

If both assemblies are strong-named (signed), the CLR will always load from the GAC.

Here are the steps the runtime uses to resolve assembly references (from How the Runtime Locates Assemblies):

  1. Determines the correct assembly version by examining applicable
    configuration files, including the
    application configuration file,
    publisher policy file, and machine
    configuration file. If the
    configuration file is located on a
    remote machine, the runtime must
    locate and download the application
    configuration file first.

  2. Checks whether the assembly name has been bound to before and, if so,
    uses the previously loaded assembly.
    If a previous request to load the
    assembly failed, the request fails
    immediately without attempting to load
    the assembly.

  3. Checks the global assembly cache. If the assembly is found there, the
    runtime uses this assembly.

  4. Probes for the assembly (… some material omitted …)

As stated later in that same article:

There is no version checking for assemblies without strong names, nor does the runtime
check in the global assembly cache for assemblies without strong names.

So if you can afford to remove signing from the local assembly, the application will use it instead of the one in the GAC.

For more detail than you could probably ever want about the runtime-binding mechanisms, see Suzanne Cook’s blog.

This blog entry from Scott Hanselman also provides a great overview of the binding process.

Leave a Comment