Avoid Partial Binds


A partial bind is when only part of the assembly display name is given when loading an assembly.


Assembly.LoadWithPartialName() also uses partial binding. First, it calls Assembly.Load(). But, if that fails to find the assembly, it will return the latest version of that assembly available in the GAC.


But, avoid using any form of partial binding – it’s the cause of Dll Hell:



  • May Be Backwards-Incompatible
    What if you want version 1, but you get version 50, which is totally incompatible with the one you wanted? Apps get broken by getting the latest version, even if you get supposedly ‘compatible’ version 2. If there’s any change at all, there’s a risk of breaking compatibility.
  • May Be Forwards-Incompatible
    What if you built with version 50, but get version 1 (since that’s the only one available) – are all of your assemblies really going to be forwards-compatible? If so, that means that you aren’t allowed to add any new features – ever!
  • Can’t Safely Install Other Apps
    Installing one app can break another app calling LoadWithPartialName() by installing a newer, incompatible version of a shared assembly.
  • Breaks Assemblies Dependent On Others
    Say that A requires a certain version of B. But, you mix-and-match by loading one version of A and an incompatible version of B. Not only does that risk strange new failures, but it also risks opening up a new security hole which the makers of A didn’t expect.

For these reasons, LoadWithPartialName() has been deprecated in v2 – use Assembly.Load() instead. I vote that it’s better to fail with a good error message than to automatically use another version of an assembly. It will make a lot more sense to the user and should be easy to remedy (while failing in weird, unpredicted ways will just confuse the user and make them think that you write buggy code).

Comments (13)

  1. Adam M. says:

    What if you just want to load something simple like System.Drawing.dll? And if you did want to avoid partial binding, how would you get System.Drawing’s full name anyway?

  2. Adam M. says:

    Err, I know you can look in the GAC by hand and get the latest name, but I was wondering about how to look programmatically.

    But I guess even that’s not a good idea, since loading one from the GAC has the same downside as using LoadWithPartialName().

    So never mind that question…

    But it still seems like it’s less likely to cause problems by simply loading the most recent version of System.dll or System.Drawing.dll, say, rather than having an application fail if it’s executed on a later version of the .NET runtime with a different set of DLLs.

    That is, the chance of a breaking change in the .NET Framework core classes seems much lower than the chance of a new version of the runtime being released at some point in the future…

  3. Bryan M. says:

    Actually I have had just loading the latest version of System.Drawing.dll cause me to have a very confusing problem.  I got an InvalidCastException casting from System.Drawing.Color to System.Drawing.Color that is becuase they were different versions of System.Drawing.Color the one was the 1.0 version which our product was using at the time and the other was the 1.1 version which was loaded when using a partial name.

  4. I hesitate to talk about this because I don’t want people who don’t know about it to think, "Hey, what’s

  5. There are two types of assembly identity that the loader deals with: bind-time and after bind-time. The

  6. Bruce F says:

    OK – here’s my scenario.

    I’m developing something which works against Microsoft.Web.Administration, and since that is only in Vista and soon to be Win 2008, I can’t compile it on XP unless I use late binding.  I could hard wire the particular version, or load from a particular directory, but that would result in a dll hell of its own.  I simply want to get the latest version of Microsoft.Web.Administration.dll out of the GAC and it seems like LoadWithPartialName is exactly what I want to do.  I don’t want my code breaking just because someone put out an update to the dll.

  7. The Megalomaniac says:

    So we’re switching our code over from .NET 1 to 2 and I’m having trouble with this scenario. We have a plugin architecture with the plugin assemblies (about 200) are located in the GAC.

    The user specificies a name and we calculate the corresponding assembly name and load it from the GAC using LoadWithPartialName. We are guaranteed that we don’t care about the version since we have a defined interface. Also it is impossible to keep all the assembly versions of the plugins in sync since there are bugfixes, new versions etc.

    Now without coding up a mapping to the fully qualified name and updating it for every plugin change, how do I continue supporting this code ? The architecture that places plugins in the GAC is a possible issue but I don’t control it.

    Any suggestions ?

  8. kkv says:

    I have developed an application which uses Excel as user interface. So while deploying in another machine I need to put the Dlls in GAC as it is not possible to put the Interop office dlls in private assembly. So I need to use only LoadWithPArtialName(). Wat should I do in this case

  9. pierre says:

    Hi,

    I am scripting in powershell, and in order to be able to use AD HOC dotnet assemblies, without having to install a PS Snapin, it is very handy to use loadwithpartialname.

    The point is here to be able to do something with about one line of code (it is called a "oneliner"), this is quick and dirty and not intended to be maintained watsoever, since the command line is immediately thrown away!

    I keep using LoadWithPartialName, as the reasons invoked hereabove do not fit in my context (interactive oneliner commands at console)

  10. Charlie says:

    I am in the same situation with The megalomaniac and kkv.  What is the best practice for such situations, especially as time passes and the user has newer versions of Microsoft.Office.InterOp.Outlook?