2

ランタイムがアセンブリを見つける方法によると、ステップ2は以前に参照されたアセンブリをチェックしています。

ただし、以下のコードでは、これが確実に発生していないことがわかります。最初の行で、アセンブリがロードされます(これにより、今後のすべての呼び出しで「以前に参照されたアセンブリ」になります)。

ただし、数行後、コードがAppDomain.CurrentDomain.CreateInstanceを呼び出すと、AssemblyResolveイベントが発生し、ランタイムが要求されたアセンブリを見つけることができないことを示します。

AssemblyResolveイベントから、CurrentDomain.GetAssemblies()から直接アセンブリを返しているため、アセンブリがロードされていることがわかります。

したがって、明らかな質問は、「ランタイムがアセンブリを見つける方法」のステップ2が意味するように、ランタイムが参照されたアセンブリを見つけられないのはなぜですか?

この例を実行するには、次のようにします。新しいコンソールアプリを作成し、そのソリューションに新しいClassLibraryを追加して、ClassLibrary1という名前のままにします。以下のコードをコンソールアプリケーションのクラスプログラムに貼り付けます。

class Program
{
    static void Main(string[] args)
    {
        Assembly asmbly = Assembly.LoadFile(Path.GetFullPath(@"..\..\..\ClassLibrary1\bin\Debug\ClassLibrary1.dll"));
        Type firstType = asmbly.GetTypes().First();
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        object myInstance = AppDomain.CurrentDomain.CreateInstance(asmbly.FullName, firstType.FullName);
    }

    static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        //WHY AM I HERE?
        return AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault(p => p.FullName == args.Name);
    }
}

次に、次のような参照を使用して追加します。

using System.Reflection;
using System.IO;

ステップ4のようにランタイムがアセンブリを見つけられないように、ここに元のパスを意図的に残していることに注意してください。コードベースまたはプロービングによるアセンブリの検索シナリオは、ステップ2で定義された機能を意図的に使用しようとしているようなものです。 。ランタイムがステップ4を介してパスを見つけることができる場合、それは正しく機能します。動作していないのはステップ2です。

ありがとう。

4

2 に答える 2

3

AppDomain.CurrentDomain.CreateInstanceLoad コンテキストを使用してアセンブリを解決しようとしているときに、アセンブリが別のコンテキスト (LoadFile コンテキスト) に読み込まれたため、解決に失敗しています。

CLRバインダーの理解の「コンテキストの理解」から:

では、そもそもなぜ CLR にローダー コンテキストがあるのでしょうか。ローダー コンテキストは、アセンブリの読み込み中に読み込み順序の独立性を確保するのに役立ちます。さらに、アセンブリが別のコンテキストに読み込まれるときに、アセンブリとその依存関係を分離する手段を提供します。

イベントにサブスクライブすることで既に問題を解決しているように見えますがAssemblyResolve、要件に応じて、他にもいくつかの方法があります。

于 2010-02-03T20:03:20.340 に答える
2

これはMSDNからの引用です

LoadFile メソッドを使用して、ID が同じでパスが異なるアセンブリを読み込んで調べます。LoadFile はファイルを LoadFrom コンテキストにロードせず、Lo​​adFrom メソッドのようにロード パスを使用して依存関係を解決しません。LoadFile は、この限定されたシナリオで役立ちます。これは、LoadFrom を使用して、ID が同じでパスが異なるアセンブリを読み込むことができないためです。最初のそのようなアセンブリのみをロードします。

これは、アセンブリをロードするために使用される方法が参照の解決にどのように影響するかについて詳しく説明している素晴らしい記事です。

特に、この記事では、LoadFile がアセンブリを「どちらのコンテキストにも」ロードしないと述べています。

于 2010-02-03T19:59:38.053 に答える