11

設定は次のとおりです。

純粋なDotNETクラスライブラリは、管理されていないデスクトップアプリケーションによってロードされます。クラスライブラリはプラグインとして機能します。このプラグインは、独自の小さな赤ちゃんプラグイン(すべてのDotNETクラスライブラリ)をロードし、dllをバイトストリームとしてメモリに読み込んでからロードします。

Assembly asm = Assembly.Load(COFF_Image);

これらの小さな赤ちゃんプラグインが他のdllへの参照を持っている場合に問題が発生します。それらはディスクから直接ではなくメモリを介してロードされるため、フレームワークはこれらの参照されたアセンブリを見つけることができないことが多く、したがってそれらをロードすることができません。

AssemblyResolverハンドラーをプロジェクトに追加すると、これらの参照されたアセンブリが削除されるのを確認できます。これらの参照されたアセンブリをディスク上のどこに配置するかについてはかなり良い考えがありますが、ロードするAssmeblyが正しいものであることを確認するにはどうすればよいですか?

要するに、このdllが隠れている可能性のあるすべてのフォルダーのリストがあると仮定して、System.ResolveEventArgs.Nameフィールドからdllファイルパスに確実に移動するにはどうすればよいですか?

4

3 に答える 3

7

過去にこれを使用したときは、ファイル名を名前を持つ ResolveEventArgs.Name の部分と比較しただけです。まったく同じバージョンをロードしていることを確認したい場合は、名前が一致するかどうかを確認し、一致する場合はアセンブリをロードしてから、アセンブリのフル ネームを ResolveEventArgs.Name と照合します。

これらの行に沿って何か:

string name = GetAssemblyName (args); //gets just the name part of the assembly name
foreach (string searchDirectory in m_searchDirectories)
    {
    string assemblyPath = Path.Combine (executingAssemblyPath, searchDirectory);
    assemblyPath = Path.Combine (assemblyPath, name + ".dll");        
    if (File.Exists (assemblyPath))
        {            
        Assembly assembly = Assembly.LoadFrom (assemblyPath);
        if (assembly.FullName == args.Name)
            return assembly;
        }
    }

完全を期すために:

private string GetAssemblyName (ResolveEventArgs args)
    {
    String name;
    if (args.Name.IndexOf (",") > -1)
        {
        name = args.Name.Substring (0, args.Name.IndexOf (","));
        }
    else
        {
        name = args.Name;
        }
    return name;
    }
于 2010-04-28T12:55:50.490 に答える
2

Managed Extensibility Framework (MEF)は、あらゆる問題を解決してくれるもののように思えます。フォルダーをスキャンして DLL を見つけ、任意の深さの依存関係を解決し、プラグイン構成全般を管理します。各パーツ (または「プラグイン」) は、必要なものと提供するものを宣言するだけで、MEF が配線を処理します。MEF が VS2010 の拡張性獣を飼いならすことに成功した場合、MEF は何でも処理できます。

于 2010-04-28T13:23:25.103 に答える
1

私は AssemblyResolver で運が良かったことは一度もありません。私は通常、次の 3 つのいずれかを行います。

  1. プラグインが GAC にない外部参照を持っていないことを要求します。彼らがビッチなら、ILMergeに伝えてください。
  2. すべての dll を既知のプラグイン ディレクトリにダンプするようプラグインに要求します。そのディレクトリ内のすべてのアセンブリをメモリに読み込みます。
  3. Fusion によってプローブされるパスにプラグインの依存関係が存在する必要があります。バインダーがアセンブリを探している場所を把握するには、フュージョン ログを有効にします (fuslogvw.exe -- ログを有効にした後は、忘れずに再起動してください)。
于 2010-04-28T12:55:15.130 に答える