다음을 통해 공유


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

  • Anonymous
    January 26, 2006
    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?

  • Anonymous
    January 26, 2006
    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...

  • Anonymous
    February 22, 2006
    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.

  • Anonymous
    April 12, 2007
    I hesitate to talk about this because I don't want people who don't know about it to think, "Hey, what's

  • Anonymous
    April 12, 2007
    There are two types of assembly identity that the loader deals with: bind-time and after bind-time. The

  • Anonymous
    July 24, 2007
    The comment has been removed

  • Anonymous
    November 15, 2007
    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 ?

  • Anonymous
    January 09, 2008
    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

  • Anonymous
    September 19, 2008
    The comment has been removed

  • Anonymous
    October 07, 2009
    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?