【问题标题】:Why do we so many kinds of assembly loading methods?为什么我们有这么多种程序集加载方法?
【发布时间】:2011-04-17 01:27:39
【问题描述】:

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

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

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

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

非常感谢。

【问题讨论】:

    标签: c# .net vb.net clr


    【解决方案1】:

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

    如果你想故意破坏规则,你需要另外两个。如果要加载不在正常探测路径中的程序集,则使用 LoadFrom()。插件很常见,例如当它们存储在不同的目录中时。加载预期的程序集不会有任何问题,但您确实通常会遇到它所依赖的程序集的问题。

    LoadFile() 也可以做到这一点,但也违反了“不要多次加载”规则。这是非常非常罕见的,这是你想要的。仅在您希望加载具有相同标识但存储在不同路径中的程序集副本的情况下才有用。例如,某种转储程序集元数据的工具。在所有其他情况下避免它,它只会导致痛苦。从这样的程序集加载的类型永远不会与从该程序集的另一个副本加载的完全相同的类型兼容。即使是同一个副本。

    【讨论】:

      【解决方案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) 方法,其中字符串是程序集名称。

      【讨论】:

        【解决方案3】:

        比较隐蔽,没有直接命名,而是Assembly.LoadFrom从URI加载程序集,所以可以指定非本地路径;而Assembly.Load 仅在本地加载。

        这在给LoadFrom的备注中:

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

        msdn

        【讨论】:

          猜你喜欢
          • 2015-02-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多