139

LoadFile我正在查看 msdn 文档,但对于使用程序集和LoadFrom加载程序集时的区别,我仍然有些困惑。有人可以提供一个例子或类比来更好地描述它。MSDN 文档让我更加困惑。此外,除了它仅在反射模式下加载程序集之外,ReflectionOnlyLoadFrom其他相同。LoadFrom

由于我的 .NET 经验不是最好的,这里有一些关于使用 LoadFile 的 MSDN 文档的问题:

LoadFile1)检查具有相同标识但位于不同路径的程序集是什么意思?身份是什么(例子)?

2) 它声明LoadFile不将文件加载到“LoadFrom Context”中,并且不使用加载路径解析依赖关系。这是什么意思,有人可以举个例子吗?

3)最后,它指出这LoadFile在这种有限的情况下很有用,因为 LoadFrom 无法加载具有相同身份但路径不同的程序集;它只会加载第一个这样的程序集,这又让我想到了同样的问题,程序集的身份是什么?

4

7 回答 7

100

这清楚了吗?

// 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 的 Assembly Identity

有很多规则可以控制程序集的加载方式,其中一些规则与它们如何解决依赖关系有关 - 如果您的 AssemblyA 依赖于 AssemblyB,.NET 应该在哪里查找 AssemblyB?在全局程序集缓存中,它找到 AssemblyA 的同一目录,还是完全在其他地方?此外,如果它找到该程序集的多个副本,它应该如何选择使用哪一个?

LoadFrom有一套规则,而LoadFile有另一套规则。很难想象使用 的许多理由LoadFile,但是如果您需要在同一程序集的不同副本上使用反射,它就在那里。

于 2009-09-25T15:13:30.613 回答
63

来自Suzanne Cook 的博客

LoadFile 与 LoadFrom

小心——这些不是一回事。

LoadFrom() 通过 Fusion,如果已经在 LoadFrom 上下文中加载了一个程序集,则可以将其重定向到不同路径但具有相同标识的另一个程序集。

LoadFile() 根本不通过 Fusion 绑定 - 加载器只是继续并准确地加载*调用者请求的内容。它不使用 Load 或 LoadFrom 上下文。

所以, LoadFrom() 通常会给你你所要求的,但不一定。LoadFile() 适用于那些真正、真正想要确切要求的人。(*然而,从 v2 开始,策略将同时应用于 LoadFrom() 和 LoadFile(),因此 LoadFile() 不一定是请求的内容。此外,从 v2 开始,如果具有其标识的程序集位于GAC,将使用 GAC 副本。使用 ReflectionOnlyLoadFrom() 准确加载您想要的内容 - 但请注意,以这种方式加载的程序集无法执行。)

LoadFile() 有一个问题。由于它不使用绑定上下文,因此不会在其目录中自动找到其依赖项。如果它们在 Load 上下文中不可用,则必须订阅 AssemblyResolve 事件才能绑定到它们。

这里

另请参阅同一博客上的选择绑定上下文文章。

于 2009-09-25T15:13:34.887 回答
46

经过一番摸索,今天下午我自己发现了一个不同之处。

我想在运行时加载一个 DLL,而 DLL 位于另一个目录中。该 DLL 有自己的依赖项 (DLL),它们也位于同一目录中。

LoadFile():加载特定的 DLL,但不加载依赖项。因此,当第一次从 DLL 中调用其他 DLL 时,它会抛出 FileNotFoundException。

LoadFrom():加载我指定的 DLL 以及该目录中的所有依赖项。

于 2013-02-26T15:32:28.437 回答
4

注意:如果使用 8.3 路径加载一个程序集,然后从非 8.3 路径加载,它们将被视为不同的程序集,即使它们是相同的物理 DLL。

于 2013-02-15T02:45:57.193 回答
1

.NET 有不同的加载上下文。苏珊娜库克在这里写了关于它们:https ://docs.microsoft.com/en-us/archive/blogs/suzcook/choosing-a-binding-context

这是 .NET 隔离不混淆引用的方式。

于 2009-09-25T15:17:31.557 回答
0

我注意到的一个区别是:

Assembly.LoadFile - 在具有有限用户权限的不同 AppDomain 中加载程序集(差异原则)。无法执行序列化/反序列化等操作。

Assembly.LoadFrom - 以相同的用户权限(相同的原则)在相同的 AppDomain 中加载程序集。

于 2012-09-15T07:19:20.740 回答
0

就我而言,我只需要简单地删除位于 @ 的 ASP 应用程序缓存C:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files。它在站点首次运行时重建。请务必先停止 IIS。

希望这对像我这样的人有所帮助。

于 2015-07-08T23:12:35.567 回答