2017-11-16 2 views
6
  1. リフレクションを使用してクラスライブラリ(lib.dll)のメソッドを呼び出すアプリケーション(executor.exe)があります。
  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を変更する機会がありません(テストを除く)。

私が取得するために何をしたいですか:「メソッドが見つかりません」例外。なぜAppDomain.CurrentDomain.AssemblyResolveが機能しないのですか?

lib.dllから呼び出され
new JsonMediaTypeFormatter().SerializerSettings; 

。見つからない

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

私がやろうとしたもの:

しかし、それはで失敗します
  1. AppDomain.CurrentDomain.AssemblyResolve(ModuleInitializerを使用して正しく購読)を処理します。しかし、それは上昇しません。クラッシュ後、2つのNewtonsoft.Json(異なるバージョンを持つ)がAppDomainに読み込まれました。アプリの設定でバインディング
  2. <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" 
    culture="neutral" /> 
    <bindingRedirect oldVersion="4.0.0.0-5.0.0.0" newVersion="9.0.0.0" /> 
    

はい、それは動作します。しかし、私はこのソリューションを使用することはできません。合格後、2つのNewtonsoft.Json(バージョンが異なる)がAppDomainにロードされます。

<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> 
<bindingRedirect oldVersion="8.0.0.0-9.0.0.0" newVersion="9.0.0.0" /> 

例外「方法:

私はこの作品理由を理解していない
  • (oldVersion = "8.0.0.0-9.0.0.0")が、

      見つからない "とはスローしません。合格後、1 Newtonsoft.Json(9.0)がAppDomainにロードされます。しかし、私には適していません。

      なぜAppDomain.CurrentDomain.AssemblyResolveが機能しないのですか?私は2つの読み込まれたアセンブリに問題があると思いますが、この動作を変更することはできません。

  • +0

    あなたは、バージョン8が埋め込みリソースとして格納されていると述べました。どうして?どのように使用されていますか? – Evk

    答えて

    7

    なぜAppDomain.CurrentDomain.AssemblyResolveが機能しないのですか?

    イベントAppDomain.CurrentDomain.AssemblyResolveは、アセンブリの解決に失敗した場合に発生します。 Newtonsoft.Jsonアセンブリが既にアプリケーションドメインにロードされているので、あなたのケースではありません。

    System.Net.Http.Formatting.JsonMediaTypeFormatter.get_SerializerSettings()がNewtonsoft.Jsonバージョン4.5で宣言されたJsonSerializerSettingsを返すため、MissingMethodExceptionをキャッチします。 Unfortunatelly、魂のないCLR JsonSerializerSettings Newtonsoft.Json 4.5からNewtonsoft.Json 9.0のJsonSerializerSettingsと全く同じではありません。

    この問題を修正するために、アセンブリバージョンのリダイレクトのメカニズムが導入されました(参照先:bindingRedirect)。

    例外「メソッドが見つかりません」はスローされません。合格後に1 Newtonsoft.Json(9.0)がAppDomainにロードされています。しかし、私には適していません。

    実際、それはあなたが守らなければならない解決策です。あなたの最善の選択肢は、アプリケーションドメインにロードされたNewtonsoft.Jsonアセンブリを1つしか持たずに、バージョンリダイレクションを設定することです。

    なぜ車輪を改革し、プラットフォームのオファー以外の解決策を見つけようとしますか?いくつかの奇妙な理由でアプリケーションの設定を変更することが禁止されている場合、マシンレベルでアセンブリリダイレクトを追加することができます 詳細はarticleを参照してください。しかしアセンブリバージョンのリダイレクトは永遠のDLL hell problemが.Netでどのように修正されるかの方法です。他の回避策を使用すると(たとえそれを見つけることができたとしても)、あなたはうまくいかないでしょう。

    3

    バインディングリダイレクトを適用できない場合は、アプリケーションの起動時に正しいアセンブリをロードすることもできます(Assembly.LoadFromメソッドを使用)。メインの方法では、Newtonsoft.Json dllを見つけ、必要なバージョンでロードします。そのため、誤ったバージョンのアセンブリを読み込まないようにする必要があります。あなたにコードスニペットを提供したい場合はお知らせください。

    +0

    OPの問題を解決しないようです。問題から、必要なアセンブリがアプリケーションドメインに読み込まれていて、最初に4.5を読み込んでもMissingMethodExceptionが修正されないことは明らかです。 – CodeFuller

    +0

    @ CodeFuller、私はまずv4.5を読み込むとv.9.0を読み込んで問題を解決できないと思います。それは基本的にバインディングリダイレクトの機能です。しかし、それは他の問題を引き起こすかもしれませんが、予測することは困難です。 OPのリダイレクトをバインドする作業をどのように理解しているので、v4.0ではなく、v4.0をロードしてください。 v4.5がドメインにロードされる前に、できるだけ早く実行してください。 –

    関連する問題