C# 具有绑定策略和解析处理程序的Assembly.LoadFrom

C# 具有绑定策略和解析处理程序的Assembly.LoadFrom,c#,.net,clr,.net-assembly,C#,.net,Clr,.net Assembly,整个情况有点复杂,所以请跟我呆一会儿,了解一下情况。。。假设我们有一些程序集: 在版本1.0.0.0中的BaseClass.dll中定义了基类 版本1.0.0.0中的DerivedClass.dll中定义了DerivedClass 主应用程序通过assembly.LoadForm()从应用程序库外部的路径加载DerviedClass.dll程序集,并尝试通过GetTypes()获取其类型,即 Assembly derived = Assembly.LoadFrom(@"..\otherdir

整个情况有点复杂,所以请跟我呆一会儿,了解一下情况。。。假设我们有一些程序集:

  • 在版本1.0.0.0中的BaseClass.dll中定义了基类
  • 版本1.0.0.0中的DerivedClass.dll中定义了DerivedClass
主应用程序通过
assembly.LoadForm()
从应用程序库外部的路径加载DerviedClass.dll程序集,并尝试通过
GetTypes()
获取其类型,即

Assembly derived = Assembly.LoadFrom(@"..\otherdir\DerivedClass.dll");
Type[] foundTypes = derived.GetTypes();
<dependentAssembly>
    <assemblyIdentity name="BaseClass"/>
    <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
如果BaseClass.dll程序集位于DerivedClass.dll的旁边(即两个程序集都位于
中)。\otherdir
,则一切正常

接下来,删除产生LoaderException的
BaseClass.dll
。若要获取有关此的详细信息,请添加AssemblyResolve处理程序

AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolver;
它只是将请求的程序集及其版本写入控制台,即

public static Assembly AssemblyResolver(object sender, ResolveEventArgs args)
{
    Console.WriteLine("Resolving " + args.Name + " from " + args.RequestingAssembly);
    return null;
}
正如所料,AssemblyResolver是用
args调用的。Name
等于
BaseClass,Version=1.0.0.0,…

现在,用版本2.0.0.0重新编译BaseClass.dll,并将其放入
otherdir
出于同样奇怪的原因,这已经起作用了。DerivedClass.dll不应该期望版本1.0.0.0,而拒绝使用版本1.0.0.0吗?

此外,如果我们添加一个将基类从版本1.0.0.0重定向到版本2.0.0.0的应用程序配置,即

Assembly derived = Assembly.LoadFrom(@"..\otherdir\DerivedClass.dll");
Type[] foundTypes = derived.GetTypes();
<dependentAssembly>
    <assemblyIdentity name="BaseClass"/>
    <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>

然后再次删除BaseClass.dll(这会产生LoaderException),AssemblyResolver仍然使用
参数调用。Name
等于
BaseClass,Version=1.0.0,…
至少现在的版本应该是
Version=2.0.0

有谁能向我解释一下,为什么更改BaseClass.dll的版本不会导致错误?为什么不使用版本2.0.0.0调用AssemblyResolver

---编辑--- 还有一个有趣的事实:对于所有具有强名称和发布者策略配置文件的程序集,Assembly.LoadFrom仅在找到版本2.0.0.0时才有效,即使有版本1.0.0.0可用,并且DerivedClass.dll是使用版本1.0.0构建的

但是,版本1.0.0.0仍调用AssemblyResolver


在我看来,调用LoadFrom程序集的AssemblyResolver时似乎没有应用发布者策略。这可能吗?

如果对其他程序集的引用不是强名称程序集,则它们将绑定到找到的任何版本。但是对其他程序集的引用是对强名称程序集的引用。此外,为什么我的AssemblyResolve在应用发布者策略后调用了该版本?无需进一步调查(我没有时间-很抱歉),我不知道还有什么好说的。如果你还没有,你可以看一看。没有问题。我已经进一步检查并更新了我的原始帖子。AssemblyResolver总是使用内置版本调用,完全忽略发布者策略。你可以始终通过配置API阅读配置部分,然后执行以下操作如果这是你想做的,你可以重定向你自己。