LoadFile vs. LoadFrom
Be careful - these aren't the same thing.
- LoadFrom() goes through Fusion and can be redirected to another assembly at a different path but with that same identity if one is already loaded in the LoadFrom context.
- LoadFile() doesn't bind through Fusion at all - the loader just goes ahead and loads exactly* what the caller requested. It doesn't use either the Load or the LoadFrom context.
So, LoadFrom() usually gives you what you asked for, but not necessarily. LoadFile() is for those who really, really want exactly what is requested. ( * However, starting in v2, policy will be applied to both LoadFrom() and LoadFile(), so LoadFile() won't necessarily be exactly what was requested. Also, starting in v2, if an assembly with its identity is in the GAC, the GAC copy will be used instead. Use ReflectionOnlyLoadFrom() to load exactly what you want - but, note that assemblies loaded that way can't be executed.)
LoadFile() has a catch. Since it doesn't use a binding context, its dependencies aren't automatically found in its directory. If they aren't available in the Load context, you would have to subscribe to the AssemblyResolve event in order to bind to them.
So, which one should you use? That depends on which binding context is right for you and whether it matters that the LoadFrom context may redirect the bind. Regarding the latter:
- If no other code can load assemblies in your AppDomain, your LoadFrom() call can prevent a redirect* by just not loading anything else with a duplicate identity.
- If you do need to load a duplicate, you could get away with it by loading it into anything other than the LoadFrom context (or into another AppDomain) instead.
- But, maybe the redirect is really okay. Are they identical assemblies, just at different paths? If yes, it may be safe to risk the redirect unless its dependencies aren't available in the dir of the first one loaded.
- Or, are they possibly different bits, just with the same assembly identity? If so, it may be unsafe to risk the redirect: maybe you'll get an more-updated/not-as-updated version which you didn't expect. Or, if it's not strongly-named, maybe this is a third-party's assembly, totally unrelated to the one you expect.
Comments
Anonymous
January 12, 2004
I use LoadFrom() to load an assembly and register the remotable types included therein. I make a call to one of these remotable types from a remote client and it fails UNLESS I put the assembly in the same directory as the host (executable). It's as if the path that was provided for the LoadFrom() is ignored by the host when it comes time to actually service a remoting call. But this seems odd, doesn't the assembly stay loaded after my LoadFrom() call? Why would it have to look for the DLL file, since I already loaded it? I must be missing something...
Thanks!Anonymous
January 28, 2004
That's because remoting's deserialization causes a call to Assembly.Load(). Since the caller (remoting) is not in the LoadFrom context, it will not be able to automatically find assemblies already loaded there. (Otherwise, the Load context would be order-dependent.) Consider changing to use the Load context instead of LoadFrom, to fix this. See http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx for more info.
It works when you move the dll to the exe's dir because that puts the dll in the Load context in the target appdomain, making it findable.Anonymous
February 18, 2004
From my tests, LoadWithPartialName has the same semantics as Load. Am I right?
ThanksAnonymous
February 18, 2004
If Load() would have succeeded, they're the same. If not, LWPN() does a partial bind to assemblies in the GAC. See http://blogs.msdn.com/suzcook/archive/2003/05/30/57159.aspx for why you should never use LWPN().Anonymous
October 04, 2004
Jon Flanders posts here about a problem he diagnosed recently about Assembly.LoadFrom() and Assembly.Load() behaving differently. The issue he basically...Anonymous
July 21, 2005
I noted on the old blogs site you had some references to Appdomain and loading the current assembly into it. But my problem has to do with referenced assemblies. I noted that assemblies seem to have no problem loading into the correct appdomain and use my shadowcopy, but the assemblies that have references to other assemblies are not being shadow copied. I know you are incredibly busy, but you seem to the only person on the wen that gets this subject. Everything out there seems fairly vague. You can get me at <my Name> at hotmailAnonymous
March 12, 2007
The comment has been removedAnonymous
May 13, 2008
InvalidCastException: Unable to cast object of Type 'X' to 'X'Anonymous
August 13, 2008
In the project i am working on i am using alot of reflection. I was having a problem with one of my reflection aspects where i was reading the types from foreach(string dll in dllsInBinDirectory) { Assembly assemb = Assembly.LoadFile(dll) readAssembly(assemb); } List<ScheduleTask> ScheduleTasks = new List<ScheduleTask>; readAssembly(Assembly assemb) { foreach(Type t in Assemb.getTypes()) { if(type.Base.Name=="ScheduleTask") { object st = Activator.CreateInstance(type); //I was having a problem casting here //InvalidCastException: Unable to cast //object /of Type 'X' to 'X' scheduleTasks.Add((ScheduleTask)type); Even though the object was of the same type, and it seemed like the type was coming from the same Assembly, there locations where different (One Assembly was in the temporary folder) and one was in the Bin folder. i found this link http://www.infini-tec.de/post/2008/05/InvalidCastException-Unable-to-cast-object-of-Type-X-to-X.aspx and Move from Assembly.LoadFile to Assembly.LoadFrom and it solved! but am i write using it in this context? } } }Anonymous
October 07, 2008
PingBack from http://blogs.msdn.com/suzcook/archive/2003/05/29/choosing-a-binding-context.aspxAnonymous
August 19, 2009
Hi Suzanne. I've a problem binding assemblies to my Excel-C# AddIn. I have to do late binding and try this like follows: public static object CreateInstanceFromExternalType( string assemblyPath, string typeName ) { try { // Externe Assembly laden Environment.CurrentDirectory = System.IO.Path.GetDirectoryName( assemblyPath ); Assembly externalAssembly = Assembly.LoadFile( assemblyPath, new Evidence( Assembly.GetExecutingAssembly().Evidence ) ); // get Typeinformation Type externalType = externalAssembly.GetType( typeName ); // create Instance return Activator.CreateInstance( externalType ); } catch ( Exception ex ) { throw ex; } } Sometimes this runs and sometimes it crashes. My Problem is, that I have to load an assembly from a third party vendor. He says, that his dlls have static linked dependencies and therefore it is absolutely neccessary to lod the original dll. obviously excel sometimes loads a temporarily copied dll and then the dependencies are missing. Because of your blog I tried to use Assembly.ReflectionOnlyLoadFrom( assemblyPath ) but then Activator.CreateInstance crashes. Is there any way to just load the original dll? thanks TeleAnonymous
October 30, 2009
Thank you for your insight. It is nice to know the difference between these methods. My problem occurs with loadfrom and loadfile. I get the "Unable to cast object of Type 'X' to 'X'" error when my code that is being ran through reflection tries to access a class that is returned from a web method. Any suggestions would be appreciated.