76

We have a web application that's deployed to many websites with only frontend changes, the shared backend portion has it's DLL in the GAC so we only have to update that one dll and all the sites get the update.

Is there a way to override the GAC with a DLL in the /bin folder to test out new features before they get released?

John Boker
  • 82,559
  • 17
  • 97
  • 130

4 Answers4

87

If it has the same version number as the referenced DLL, the GAC gets used.

If you increment the version number, rebuild the website referencing the new version number, put the new version in the /bin directory, then that DLL will be used.

If you do not want to change the version number, you're pretty much out of luck.

When .NET loads strong named assemblies, first it tries to decide what version number to use. It does this via the reference first, then it looks for publisher policies, then it looks for binding redirects in the configuration file.

After it does this, it looks for the assembly in the GAC, then in any codebase specified, then it probes various file system folders for the DLL. If at any one of those steps it finds the right version assembly, it stops.

If you are not changing the version number of your strong named assembly, .NET will find the original one in the GAC and stop looking. Note that because it stops when it finds one, and because looking in the GAC is first, specifying a codebase for your assembly will do no good unless you also specify a new version number.

Adam Sills
  • 16,896
  • 6
  • 51
  • 56
  • 2
    Do I understand this correct? If version 1.0.0.0 is in the GAC but I compile with version 1.0.0.1 and place 1.0.0.1 in my BIN, then GAC is ignored and BIN is used. If I remove the .dll from my BIN then 1.0.0.0 in the GAC will be used even though I compiled with 1.0.0.1? – J.Hendrix Feb 03 '10 at 21:22
  • 2
    No. If you compile against a strong-named assembly it will require the exact version number, unless there are publisher policy or binding redirects available. – Adam Sills Feb 04 '10 at 20:03
  • 2
    The publisher policies and binding redirects allow for version # redirection, so if your program is compiled against 1.0.0.0 and there is a binding redirect or publisher policy specifying 1.0.0.1, then that becomes the version it looks for. – Adam Sills Feb 04 '10 at 20:04
  • 2
    Once version redirection is complete, the assembly loader (fusion) probes various locations for the assembly. If it can't find the right version, you get an exception. – Adam Sills Feb 04 '10 at 20:05
  • 1
    So in your case, you compiled against 1.0.0.1. If it can't find that version (no matter where it looks), you get an exception. – Adam Sills Feb 04 '10 at 20:05
  • What means "It does this via the reference first"? – NullReference Nov 25 '16 at 10:00
  • @August - it's related to the previous sentence, which talks about figuring out the version number. It does that by looking at the reference first. – Adam Sills Nov 28 '16 at 15:47
  • @August - "via" can mean "by way of" or "by means of" – Adam Sills Nov 28 '16 at 15:48
11

I have been able to override the GAC with the assembly in the \bin folder using the <codebase>Element.

By specifying <codebase version="1.2.3.4" href="/bin/MyAssembly.dll" /> in my web.config file I can tell my application to use this version rather than the version specified in the GAC.

You may also want to take a look at the <probing>Element for specifying assembly locations?

IsolatedStorage
  • 1,175
  • 12
  • 12
  • 7
    you should double check that your dll's are signed or not. GAC takes precedence over codebase and probe. Once it finds the signed version in GAC it stops. I tested this with 4.0 and the MSDN doc is accurate, first BindingRedirect, then GAC, then CodeBase, then Probe for StrongName assemblies – CodeCowboyOrg Mar 10 '15 at 21:25
  • This only works if the used assembly version is a higher than the version of the assembly in the GAC. As the previous comment says, if the version number is identical to the assembly in the GAC you can not “override” the GAC resolution. The GAC takes preference. See [”How the Runtime Locates Assemblies”](https://learn.microsoft.com/en-us/dotnet/framework/deployment/how-the-runtime-locates-assemblies) – Kissaki May 29 '19 at 14:00
2

I think I might be saying the same think as Adam Sills, but re-worded it for my understanding. Through my own testing, looks like this is what happens:

  • If your app is compiled with version 1.0.0.0 and 1.0.0.1 is in the GAC, then you can omit the .dll from your /bin.
  • If your app is compiled with version 1.0.0.1 and 1.0.0.0 is in the GAC, then you MUST place the .dll in your /bin to ignore the GAC. A error will occur if the GAC version is older than the required version of your app, unless you include the newer version in your /bin.

I hope this is correct...

J.Hendrix
  • 2,199
  • 4
  • 20
  • 26
  • 1
    The .NET Framework will *not* do version redirection of strong named assemblies automatically, at least as of .NET 3.5 (.NET 2.0 runtime). Theoretically .NET 4 could change the rules, but I doubt it. – Adam Sills Feb 04 '10 at 20:13
  • 1
    Thanks! I now see why my tests worked with different versions. I thought the strong name was just the key you register it with. But I actually have two assemblies registered in the GAC 1.0.0.0 and 1.0.0.1 both with the same public key token. I thought that if I used the same key, 1.0.0.1 would replace 1.0.0.0. But that does not appear to be the case.
    Thanks @Adam for you help!
    – J.Hendrix Feb 05 '10 at 20:39
0

You can view binding information in the log file using the Assembly Binding Log Viewer (Fuslogvw.exe), which is included in the Windows Software Development Kit (SDK).

s

BALKANGraph
  • 2,031
  • 1
  • 15
  • 16