使用.NET 程序集的 LoadFile 和 LoadFrom 之间的区别?

我查看了 msdn 文档,对于在加载程序集时使用 LoadFileLoadFrom之间到底有什么区别,我仍然有些困惑。有人能提供一个例子或类比来更好地描述它吗。MSDN 文档更让我困惑。此外,ReflectionOnlyLoadFrom是否与 LoadFrom相同,只是它只在反射模式下加载程序集。

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

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

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

3)最后,它指出 LoadFile在这个有限的场景中是有用的,因为 LoadFrom 不能加载具有相同标识但不同路径的程序集; 它只会加载第一个这样的程序集,这又带给我同样的问题,什么是程序集标识?

60141 次浏览

这样说清楚了吗?

// 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 谈装配身份

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

LoadFrom有一组规则,而 LoadFile有另一组规则。很难想象使用 LoadFile的许多原因,但是如果您需要在同一程序集的不同副本上使用反射,那么 LoadFile就可以满足您的需要。

来自 Suzanne Cook 的博客:

LoadFile 与 LoadFrom

小心点,这些不一样 东西。

LoadFrom ()经过 Fusion 并且可以被重定向到另一个 装配在不同的路径,但使用 同样的身份,如果一个人已经 在 LoadFrom 上下文中加载。

LoadFile ()根本不会通过 Fusion 进行绑定——加载程序会自动启动 提前加载完全 * 呼叫请求。它不使用 LoadFrom 或 LoadFrom 背景。

所以,LoadFrom ()通常会给出 你要求的,但不一定。 LoadFile ()是为那些真正, 真正想要的是所要求的东西。 (* 不过,从 v2开始,策略将 都应用于 LoadFrom ()和 LoadFile () ,所以 LoadFile ()不会 必然是原来的样子 此外,从 v2开始,如果 程序集及其标识位于 GAC,GAC 的副本将被使用 使用 RefectionOnlyLoadFrom () 装载你想要的东西,但是, 注意,程序集是以这种方式加载的 不能执行。)

LoadFile ()有一个捕获 不使用绑定上下文,它的 依赖关系不是自动产生的 在它的目录中找到。如果他们不是 可在 Load 上下文中使用,则 必须订阅 事件以进行绑定 对他们来说。

参见 给你

也可以在同一个博客上看到 选择绑定上下文的文章。

.NET 有不同的加载上下文

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

我注意到的一个不同之处是:

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

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

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

今天下午我自己也发现了一个不同的地方。

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

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

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

在我的例子中,我只需要删除位于@C:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files的 ASP 应用程序缓存。它在站点首次运行时重新构建。一定要先停止 IIS。

希望这能帮到像我一样的人。