C# 为什么我们需要这么多种装配加载方法?

C# 为什么我们需要这么多种装配加载方法?,c#,.net,vb.net,clr,C#,.net,Vb.net,Clr,首先,有3种方法可以将程序集加载到AppDomain中: Assembly.Load() Assembly.LoadFrom() Assembly.LoadFile()文件 LoadFrom()方法将程序集文件路径作为其参数,但文件路径仅提供程序集标识信息作为CLR的线索。LoadFrom()方法仍然使用该标识信息在内部调用Load()。因此,很可能LoadFrom(filepath)将加载与filepath指定的程序集完全不同的程序集。但是tame LoadFile()方法将只加载我们指定

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

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

我想知道为什么我们需要LoadFrom()方法?这只会增加混乱和陷阱。是否存在只适用于LoadFrom()的场景


非常感谢。

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

这在
LoadFrom
的备注中:

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


参见

关于这一点,实际上有很多讨论,但有一些不同的观点:

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

来自MSDN

使用LoadFile方法来加载和 检查具有相同属性的程序集 身份,但位于不同的位置 路径。LoadFile不加载文件 进入LoadFrom上下文,并执行以下操作 不使用 加载路径,如LoadFrom方法 做LoadFile在这方面很有用 有限的场景,因为LoadFrom 无法用于加载以下程序集: 有相同的身份但不同 路径;它将只加载第一个 这样的集会

从我收集到的信息来看,似乎形成了一个不稳定的共识,即应该远离LoadFile(),如果可以,使用Load(),如果需要,使用LoadFrom()。但我也看到有人说远离LoadFrom()


作为数据点,在Ecma CLI标准()中,我们只标准化了Assembly.Load(string)方法,其中字符串是程序集名称。

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

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

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