我正在查看msdn文档,我仍然对加载程序集时使用LoadFile
和LoadFrom
之间的区别有点困惑。有人可以提供一个例子或类比来更好地描述它。 MSDN文档让我更加困惑。此外,ReflectionOnlyLoadFrom
与LoadFrom
相同,只是它仅以反射模式加载程序集。
由于我的.NET经验不是最好的,所以这里有一些关于使用LoadFile的MSDN文档的问题:
1)LoadFile
检查具有相同标识但位于不同路径的程序集是什么意思?身份是什么(例子)?
2)它声明LoadFile
不会将文件加载到'LoadFrom上下文'中,并且不会使用加载路径解析依赖关系。这意味着什么,有人可以提供一个例子吗?
3)最后,它指出LoadFile
在这种有限的场景中很有用,因为LoadFrom无法加载具有相同身份但路径不同的程序集;它只会加载第一个这样的组件,这再次引发了我同样的问题,组件标识是什么?
答案 0 :(得分:88)
这清楚了吗?
// 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);
修改:要回答您在修订后的问题中提出的问题,请务必阅读Suzanne Cook on Assembly Identity。
有很多规则可以控制程序集的加载方式,其中一些规则与它们如何解决依赖关系有关 - 如果你的AssemblyA依赖于AssemblyB,.NET应该在哪里查找AssemblyB?在全局程序集缓存中,它找到AssemblyA的相同目录,还是完全在其他地方?此外,如果它找到该程序集的多个副本,它应该如何选择使用哪个?
LoadFrom
有一套规则,而LoadFile
则有另一套规则。很难想象使用LoadFile
的许多理由,但是如果你需要在同一个程序集的不同副本上使用反射,它就在那里。
答案 1 :(得分:57)
LoadFile与LoadFrom
小心 - 这些不一样 的事情。
LoadFrom()通过Fusion并可以重定向到另一个 装配在不同的路径,但与 如果已经存在相同的身份 在LoadFrom上下文中加载。
LoadFile()根本没有通过Fusion绑定 - 加载器就是这样 提前并正好加载* 来电者要求。它不使用 Load或LoadFrom 上下文。
所以,LoadFrom()通常会给你什么 你问过,但不一定。 LoadFile()适合那些真正的, 真正想要的确切要求。 (*但是,从v2开始,政策将会 适用于LoadFrom()和 LoadFile(),所以LoadFile()不会 必然正是如此 请求。另外,从v2开始,如果是 具有身份的装配在 GAC,将使用GAC副本 代替。使用ReflectionOnlyLoadFrom() 加载你想要的 - 但是, 请注意,程序集以这种方式加载 无法执行。)
LoadFile()有一个catch。既然如此 它不使用绑定上下文 依赖关系不是自动的 在其目录中找到。如果他们不是 你可以在Load上下文中找到它 必须订阅 AssemblyResolve事件以便绑定 他们。
请参阅here。
另请参阅同一博客上的Choosing a Binding Context文章。
答案 2 :(得分:38)
经过多次头疼之后,我今天下午发现了一个与众不同的地方。
我想在运行时加载DLL,DLL存在于另一个目录中。该DLL有自己的依赖项(DLL),它们也存在于同一目录中。
LoadFile():加载特定的DLL,但不加载依赖项。因此,当第一次调用从DLL内部发送到其他DLL之一时,它会抛出一个FileNotFoundException。
LoadFrom():加载我指定的DLL以及该目录中的所有依赖项。
答案 3 :(得分:3)
注意:如果使用8.3路径加载一个程序集,然后从非8.3路径加载它们,则它们将被视为不同的程序集,即使它们是相同的物理DLL。
答案 4 :(得分:2)
我注意到的一个区别是:
Assembly.LoadFile - 在具有有限用户权限的不同AppDomain中加载程序集(diffrence principel)。无法进行血清/消毒等手术。
Assembly.LoadFrom - 在具有相同用户权限的同一AppDomain中加载程序集(相同的原则)。
答案 5 :(得分:1)
.NET具有不同的加载上下文。 Suzanne Cook在这里写到了他们:http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx
这就是.Net隔离引用不混淆的方式。
答案 6 :(得分:0)
就我而言,我只需删除位于@ C:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files
的ASP应用程序缓存。首次运行站点时会重建它。请务必先停止IIS。
希望这可以帮助像我这样的人。