为什么我们这么多种装配方法呢?

时间:2010-09-25 01:13:30

标签: c# .net vb.net clr

AFAIK,有3种方法可以将程序集加载到AppDomain中:

  • Assembly.Load()
  • Assembly.LoadFrom()
  • Assembly.LoadFile()

LoadFrom()方法将程序集文件路径作为参数,但文件路径仅提供程序集标识信息作为CLR的线索。 LoadFrom()方法仍然在内部使用该标识信息调用Load()。因此,LoadFrom(filepath)很可能会从文件路径指定的程序集加载完全不同的程序集。但是温和的LoadFile()方法只会加载我们指定的程序集。

我想知道为什么我们需要LoadFrom()方法?它只会增加混乱和陷阱。是否有任何场景只有LoadFrom()适用?

非常感谢。

3 个答案:

答案 0 :(得分:2)

实际上有很多关于此的讨论,有一些不同的意见:

Difference between LoadFile and LoadFrom with .NET Assemblies?

http://geekswithblogs.net/rupreet/archive/2010/02/16/137988.aspx

http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/3bdaf65c-520c-4a1a-a825-fc2ca2957bf3

http://blogs.microsoft.co.il/blogs/sasha/archive/2007/03/06/Assembly-Load-Contexts-Subtleties.aspx

回答有关为何需要LoadFrom()方法的问题。好吧,它似乎归结为想要从特定位置和依赖项加载。 Load()解析依赖关系,但不允许您选择程序集的位置(即,在尝试找到程序集的位置有一组“探测”结构)。 LoadFile()保证您将加载指定的程序集作为字符串参数,但不解析依赖项。 LoadFrom()不保证您将加载路径中提供的程序集(即,如果已加载具有类似标识的程序集),但它确实为您解析了依赖项。

来自MSDN

  

使用LoadFile方法加载和   检查具有相同的程序集   身份,但位于不同的   路径。 LoadFile不加载文件   进入LoadFrom上下文,并做到了   不使用。解决依赖关系   加载路径,作为LoadFrom方法   确实。 LoadFile在这方面很有用   有限的情况因为LoadFrom   不能用于加载那些组件   具有相同的身份但不同   路径;它只会加载第一个   这样的集会。

根据我收集的内容,似乎形成一种不稳定的共识,即应该远离LoadFile(),如果可以,请使用Load(),如果需要,请使用LoadFrom()。但我看到有人说远离LoadFrom()。

作为数据点,在Ecma CLI标准(http://www.ecma-international.org/publications/standards/Ecma-335.htm)中,我们只标准化了Assembly.Load(string)方法,其中字符串是程序集名称。

答案 1 :(得分:2)

您应始终使用Assembly.Load()。只有那种方法才能保证可预测的结果。它避免了DLL Hell,并确保程序集只加载一次,即使代码加载多次也是如此。

如果你想故意破坏规则,你需要另外两个。如果要加载不在正常探测路径中的装配,则使用LoadFrom()。插件很常见,例如当它们存储在不同的目录中时。您可以毫无问题地加载预期的程序集但是通常会对它所依赖的程序集产生问题。

LoadFile()也会执行此操作,但也会破坏“不要多次加载”规则。这是你想要的非常非常罕见。仅在您要加载具有相同标识但存储在不同路径中的程序集副本的情况下才有用。例如,转储程序集元数据的某种工具。在所有其他情况下避免它,它只会造成痛苦。从这样的程序集加载的类型永远不会与从程序集的另一个副本加载的完全相同的类型兼容。即使是同一份副本。

答案 2 :(得分:0)

它非常隐藏,并且没有直接命名,但是Assembly.LoadFrom从URI加载程序集,因此您可以指定非本地路径;而Assembly.Load仅在本地加载。

这是LoadFrom的备注:

  

assemblyFile参数必须引用不带转义字符的URI。此方法为URI中的所有无效字符提供转义字符。

请参阅msdn