“未找到方法”例外。为什么AppDomain.CurrentDomain.AssemblyResolve不起作用?

时间:2017-11-16 01:39:03

标签: c# .net

  1. 有一个应用程序(executor.exe)使用反射调用类库(lib.dll)中的方法。
  2. executor.exe将程序集Newtonsoft.Json 8.0作为嵌入式资源。
  3. lib.dll引用了Newtonsoft.Json 9.0版。
  4. lib.dll引用了system.net.http.formatting版本4.0.0.21112,后者又引用了Newtonsoft.Json 4.5。
  5. 我没有机会修改executor.exe.config(测试除外)。
  6. 我想得到什么:

    new JsonMediaTypeFormatter().SerializerSettings;
    

    从lib.dll调用。但它失败了:

      

    找不到方法:'Newtonsoft.Json.JsonSerializerSettings   System.Net.Http.Formatting.JsonMediaTypeFormatter.get_SerializerSettings()'

    我想做的事情:

    1. 处理AppDomain.CurrentDomain.AssemblyResolve(使用ModuleInitializer正确订阅)。但它并没有上升。崩溃后,将2个Newtonsoft.Json(带有不同版本)加载到AppDomain。
    2. 在app config中绑定:

       <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed"
       culture="neutral" />
       <bindingRedirect oldVersion="4.0.0.0-5.0.0.0" newVersion="9.0.0.0" />
      
    3. 是的,它有效。但我不能使用这个解决方案。传递后将2个Newtonsoft.Json(带有不同版本)加载到AppDomain。

      1. 我不明白为什么会这样(oldVersion =“8.0.0.0-9.0.0.0”)但是:

        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="8.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
        
      2. 异常“未找到方法”不抛出。传递后将1个Newtonsoft.Json(9.0)加载到AppDomain。但不适合我。

        为什么AppDomain.CurrentDomain.AssemblyResolve不起作用?我想问题是在2个加载的程序集中,但我不能改变这种行为。

2 个答案:

答案 0 :(得分:7)

  

为什么AppDomain.CurrentDomain.AssemblyResolve不起作用?

如果程序集解析失败,则会触发事件AppDomain.CurrentDomain.AssemblyResolve。由于您在应用程序域中已经加载了Newtonsoft.Json程序集,因此不是您的情况。

您抓住MissingMethodException因为System.Net.Http.Formatting.JsonMediaTypeFormatter.get_SerializerSettings()返回在Newtonsoft.Json 4.5版中声明的JsonSerializerSettings。 不幸的是,来自Newtonsoft.Json 4.5的没有灵魂的CLR JsonSerializerSettings与来自Newtonsoft.Json 9.0的JsonSerializerSettings完全不同。

为解决此问题,引入了程序集版本重定向机制(您引用的bindingRedirect)。

  

例外&#34;未找到方法&#34;不扔。通过后有1   Newtonsoft.Json(9.0)加载到AppDomain。但不适合我。

实际上,这是你应该坚持的解决方案。您最好的选择是只将一个Newtonsoft.Json程序集加载到应用程序域中并配置版本重定向。

为什么要重新发明轮子并尝试寻找平台优惠以外的解决方案?如果出于某种奇怪的原因,您被禁止修改应用程序配置,则可以在计算机级别添加程序集重定向 有关详细信息,请参阅此article。但是汇编版本重定向是在.Net中修复永恒DLL hell problem的方式。使用任何其他解决方法(即使你设法找到它们)也会让你感觉不舒服。

答案 1 :(得分:3)

如果您无法应用绑定重定向,您还可以在应用程序启动时使用Assembly.LoadFrom方法加载正确的程序集。在main方法中找到Newtonsoft.Json dll并加载一个你需要的版本。这应该避免加载错误版本的程序集。如果您希望我为您提供代码段,请与我们联系。