LoadFile 和 LoadFrom 与 .NET 程序集的区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1477843/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between LoadFile and LoadFrom with .NET Assemblies?
提问by Xaisoft
I was looking at the msdn documentation and I am still a little confused on what exactly is the difference between using LoadFileand LoadFromwhen loading an assembly. Can someone provide an example or an analogy to better describe it. The MSDN documentation confused me more. Also, Is ReflectionOnlyLoadFromthe same as LoadFromexcept that it loads the assembly only in reflection mode.
我正在查看 msdn 文档,但我仍然对使用LoadFile和LoadFrom加载程序集时到底有什么区别感到有些困惑。有人可以提供一个例子或类比来更好地描述它。MSDN 文档让我更加困惑。此外,除了它仅在反射模式下加载程序集之外,ReflectionOnlyLoadFrom与其他相同LoadFrom。
Since my .NET experience is not the greatest, here are some questions regarding the MSDN documentation using LoadFile:
由于我的 .NET 经验不是最好的,这里有一些关于使用 LoadFile 的 MSDN 文档的问题:
1) What does it mean by LoadFileexamines assemblies that have the same Identity, but are located in different paths? What is the identity (example)?
1)LoadFile检查具有相同标识但位于不同路径的程序集是什么意思?身份(示例)是什么?
2) It states the LoadFiledoes not load files into the 'LoadFrom Context' and does not resolve dependencies using the load path. What does this mean, can someone provide an example?
2) 它声明LoadFile不会将文件加载到“LoadFrom Context”中,并且不会使用加载路径解析依赖项。这是什么意思,谁能举个例子?
3) Lastly, it states that LoadFileis useful in this limited scenario because LoadFrom cannot load assemblies that have the same identities but different paths; it will only load the first such assembly, which again brings me to the same question, what is the assemblies identity?
3) 最后,它指出这LoadFile在此有限场景中很有用,因为 LoadFrom 无法加载具有相同身份但路径不同的程序集;它只会加载第一个这样的程序集,这又让我想到了同样的问题,程序集标识是什么?
采纳答案by Jeff Sternal
Does this clear it up?
这清楚了吗?
// path1 and path2 point to different copies of the same assembly on disk:
Assembly assembly1 = Assembly.LoadFrom(path1);
Assembly assembly2 = Assembly.LoadFrom(path2);
// These both point to the assembly from path1, so this is true
Console.WriteLine(assembly1.CodeBase == assembly2.CodeBase);
assembly1 = Assembly.LoadFile(path1);
assembly2 = Assembly.LoadFile(path2);
// These point to different assemblies now, so this is false
Console.WriteLine(assembly1.CodeBase == assembly2.CodeBase);
Edit: to answer the questions you raised in your revised question, you definitely want to read Suzanne Cook on Assembly Identity.
编辑:要回答您在修改后的问题中提出的问题,您肯定想阅读关于 Assembly Identity 的 Suzanne Cook。
There are a lot of rules that govern how assemblies are loaded, and some of them have to do with how they resolve dependencies - if your AssemblyA is dependent on AssemblyB, where should .NET look to find AssemblyB? In the Global Assembly Cache, the same directory it found AssemblyA, or somewhere else entirely? Furthermore, if it finds multiple copies of that assembly, how should it choose which one to use?
有很多规则控制程序集的加载方式,其中一些规则与它们如何解决依赖关系有关 - 如果您的 AssemblyA 依赖于 AssemblyB,那么 .NET 应该在哪里寻找 AssemblyB?在全局程序集缓存中,它在同一目录中找到了 AssemblyA,还是完全在其他地方?此外,如果它发现该程序集的多个副本,它应该如何选择使用哪一个?
LoadFromhas one set of rules, while LoadFilehas another set of rules. It is hard to imagine many reasons to use LoadFile, but if you needed to use reflection on different copies of the same assembly, it's there for you.
LoadFrom有一套规则,而LoadFile有另一套规则。很难想象有很多理由使用LoadFile,但是如果您需要在同一程序集的不同副本上使用反射,它就在您身边。
回答by CraigTP
From Suzanne Cook's blog:
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.
LoadFile 与 LoadFrom
小心 - 这些不是一回事。
LoadFrom() 通过 Fusion 并且可以重定向到位于不同路径但具有相同标识的另一个程序集,如果一个程序集已在 LoadFrom 上下文中加载。
LoadFile() 根本不通过 Fusion 绑定 - 加载器只是继续加载*调用者请求的内容。它不使用 Load 或 LoadFrom 上下文。
因此, LoadFrom() 通常会提供您所要求的内容,但不一定。LoadFile() 适用于那些真正非常想要所请求内容的人。(*但是,从 v2 开始,策略将同时应用于 LoadFrom() 和 LoadFile(),因此 LoadFile() 不一定是请求的内容。此外,从 v2 开始,如果具有其标识的程序集在GAC,将使用 GAC 副本。使用 ReflectionOnlyLoadFrom() 准确加载您想要的内容 - 但请注意,无法执行以这种方式加载的程序集。)
LoadFile() 有一个问题。由于它不使用绑定上下文,因此不会在其目录中自动找到其依赖项。如果它们在 Load 上下文中不可用,则必须订阅 AssemblyResolve 事件才能绑定到它们。
See here.
见这里。
Also see Choosing a Binding Contextarticle on the same blog.
另请参阅同一博客上的选择绑定上下文文章。
回答by LordWilmore
After a lot of head-scratching I've discovered a difference myself this afternoon.
经过大量的挠头之后,我今天下午发现了自己的不同。
I wanted to load a DLL at runtime, and the DLL lived in another directory. That DLL had its own dependencies (DLLs) which also lived in that same directory.
我想在运行时加载一个 DLL,而 DLL 位于另一个目录中。该 DLL 有自己的依赖项 (DLL),它们也位于同一目录中。
LoadFile(): Loaded the specific DLL, but not the dependencies. So when the first call was made from within the DLL to one of those other DLLs it threw a FileNotFoundException.
LoadFile():加载特定的 DLL,但不加载依赖项。因此,当从 DLL 内部对其他 DLL 中的一个进行第一次调用时,它会抛出 FileNotFoundException。
LoadFrom(): Loaded the DLL that I specified and also all the dependencies that lived in that directory.
LoadFrom():加载我指定的 DLL 以及位于该目录中的所有依赖项。
回答by Gregg DeMasters
Note: If one assembly is loaded using an 8.3 path, and then from a non-8.3 path, they will be seen as different assemblies, even though they are the same physical DLL.
注意:如果一个程序集使用 8.3 路径加载,然后从非 8.3 路径加载,它们将被视为不同的程序集,即使它们是相同的物理 DLL。
回答by Arthur
.NET has different load context. Suzanne Cook wrote about them here: http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx
.NET 有不同的加载上下文。Suzanne Cook 在这里写了他们的文章:http: //blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx
This is the way .Net quarantines that references are not mixed up.
这就是引用不会混淆的 .Net 隔离方式。
回答by Lalit
one difference that i noticed is:
我注意到的一个区别是:
Assembly.LoadFile- Loads assembly in different AppDomain with limited user rights (diffrence principel). operations like serilization/deserilization could not be performed.
Assembly.LoadFile- 以有限的用户权限(差异原则)在不同的 AppDomain 中加载程序集。无法执行诸如灭菌/除菌之类的操作。
Assembly.LoadFrom- Loads assembly in same AppDomain with same user rights (same principel).
Assembly.LoadFrom- 在具有相同用户权限(相同原则)的相同 AppDomain 中加载程序集。
回答by David Roth
In my case, I just had to simply delete the ASP application cache located @ C:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files. It is rebuilt when the site is first run. Be sure to stop IIS first.
就我而言,我只需删除位于 @ 的 ASP 应用程序缓存C:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files。它在站点首次运行时重建。请务必先停止 IIS。
Hope this helps someone like it did for me.
希望这能帮助像我这样的人。

