Assembly.LoadFrom with Binding Policies and Resolve Handler

时间:2014-03-08 18:49:33

标签: c# .net clr .net-assembly

整个情况有点复杂,所以请与我保持一段时间以获得上下文......假设我们有一些集会:

  • BaseClass在版本1.0.0.0
  • 中的BaseClass.dll中定义
  • DerivedClass在版本1.0.0.0
  • 中的DerivedClass.dll中定义

主应用程序通过Assembly.LoadForm()从应用程序库外部的路径加载DerviedClass.dll程序集,并尝试通过GetTypes()获取其类型,即

Assembly derived = Assembly.LoadFrom(@"..\otherdir\DerivedClass.dll");
Type[] foundTypes = derived.GetTypes();

如果BaseClass.dll程序集位于DerivedClass.dll旁边(两个程序集都在..\otherdir中,则一切都按预期工作。

接下来,删除产生LoaderException的BaseClass.dll。要获得有关此内容的更多信息,请添加AssemblyResolve Handler

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吗?

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

<dependentAssembly>
    <assemblyIdentity name="BaseClass"/>
    <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>

并再次删除BaseClass.dll(产生LoaderException),仍然调用AssemblyResolver args.Name等于BaseClass, Version=1.0.0.0, ...至少现在版本不应该是Version=2.0.0.0

有人可以向我解释,为什么更改BaseClass.dll的版本不会产生错误?为什么没有使用版本2.0.0.0调用AssemblyResolver?

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

但是,仍然使用版本1.0.0.0调用AssemblyResolver。

对我来说,当调用LoadFrom Assemblies的AssemblyResolver时,看起来似乎不应用发布者策略。这可能吗?

0 个答案:

没有答案