139

私はmsdnのドキュメントを見ていましたが、アセンブリを使用する場合LoadFileLoadFromロードする場合の正確な違いについてまだ少し混乱しています。誰かがそれをよりよく説明するための例または類推を提供できますか. MSDN のドキュメントは、私をさらに混乱させました。また、反射モードでのみアセンブリをロードすることを除いてReflectionOnlyLoadFrom、 と同じです。LoadFrom

私の .NET の経験はあまりよくないので、LoadFile を使用した MSDN ドキュメントに関するいくつかの質問を以下に示します。

LoadFile1)同じ ID を持つが、異なるパスにあるアセンブリを調べるとはどういう意味ですか? 正体(例)は?

2) はLoadFileファイルを「LoadFrom コンテキスト」にロードせず、ロード パスを使用して依存関係を解決しないと述べています。これはどういう意味ですか、誰かが例を提供できますか?

3) 最後に、LoadFileLoadFrom は ID が同じでパスが異なるアセンブリを読み込めないため、この限定されたシナリオで役立つと述べています。最初のそのようなアセンブリのみをロードするため、同じ質問が再び発生します。アセンブリのアイデンティティは何ですか?

4

7 に答える 7

100

これはそれをクリアしますか?

// path1 and path2 point to different copies of the same assembly on disk:

Assembly assembly1 = Assembly.LoadFrom(path1);
Assembly assembly2 = Assembly.LoadFrom(path2);

// These both point to the assembly from path1, so this is true
Console.WriteLine(assembly1.CodeBase == assembly2.CodeBase);

assembly1 = Assembly.LoadFile(path1);
assembly2 = Assembly.LoadFile(path2);

// These point to different assemblies now, so this is false
Console.WriteLine(assembly1.CodeBase == assembly2.CodeBase);

編集:改訂された質問で提起した質問に答えるには、AssemblyIdentityのSuzanneCookを必ず読んでください。

アセンブリのロード方法を管理するルールはたくさんあり、それらのいくつかは依存関係を解決する方法に関係しています-AssemblyAがAssemblyBに依存している場合、.NETはAssemblyBを見つけるためにどこを探す必要がありますか?グローバルアセンブリキャッシュで、AssemblyAを見つけたのと同じディレクトリ、または完全に別の場所にありますか?さらに、そのアセンブリの複数のコピーが見つかった場合、どのコピーを使用するかをどのように選択する必要がありますか?

LoadFrom1つのルールLoadFileのセットがあり、別のルールのセットがあります。使用する多くの理由を想像するのは難しいLoadFileですが、同じアセンブリの異なるコピーでリフレクションを使用する必要がある場合は、それがあります。

于 2009-09-25T15:13:30.613 に答える
63

Suzanne Cookのブログから:

LoadFileとLoadFrom

注意してください-これらは同じものではありません。

LoadFrom()はFusionを経由し、別のパスにある別のアセンブリにリダイレクトできますが、LoadFromコンテキストにすでにロードされている場合は、同じIDを使用します。

LoadFile()はFusionを介してバインドされません。ローダーは先に進み、呼び出し元が要求したものを正確にロードします*。LoadコンテキストもLoadFromコンテキストも使用しません。

したがって、LoadFrom()は通常、要求したものを提供しますが、必ずしもそうとは限りません。LoadFile()は、要求されたものを正確に知りたい人向けです。(*ただし、v2以降では、ポリシーはLoadFrom()とLoadFile()の両方に適用されるため、LoadFile()は必ずしも要求されたものとは限りません。また、v2以降では、IDを持つアセンブリがGAC、GACコピーが代わりに使用されます。ReflectionOnlyLoadFrom()を使用して、必要なものを正確にロードします。ただし、その方法でロードされたアセンブリは実行できないことに注意してください。)

LoadFile()には問題があります。バインディングコンテキストを使用しないため、その依存関係はディレクトリで自動的に検出されません。それらがLoadコンテキストで使用できない場合は、それらにバインドするためにAssemblyResolveイベントをサブスクライブする必要があります。

ここを参照してください。

同じブログの「バインディングコンテキストの選択」の記事も参照してください。

于 2009-09-25T15:13:34.887 に答える
46

何度も頭を悩ませた後、今日の午後、自分自身で違いを発見しました.

実行時に DLL をロードしたかったのですが、DLL は別のディレクトリにありました。その DLL には、同じディレクトリに存在する独自の依存関係 (DLL) がありました。

LoadFile(): 特定の DLL を読み込みましたが、依存関係は読み込みませんでした。そのため、DLL 内から他の DLL の 1 つに対して最初の呼び出しが行われたときに、FileNotFoundException がスローされました。

LoadFrom(): 指定した DLL と、そのディレクトリにあるすべての依存関係を読み込みました。

于 2013-02-26T15:32:28.437 に答える
4

注:1つのアセンブリが8.3パスを使用してロードされ、次に8.3以外のパスからロードされた場合、それらは同じ物理DLLであっても、異なるアセンブリとして表示されます。

于 2013-02-15T02:45:57.193 に答える
1

.NET には異なるロード コンテキストがあります。Suzanne Cook は、それらについてここに書いています: https://docs.microsoft.com/en-us/archive/blogs/suzcook/choosing-a-binding-context

これは、参照する .NET 検疫が混同されない方法です。

于 2009-09-25T15:17:31.557 に答える
0

私が気づいた1つの違いは次のとおりです。

Assembly.LoadFile - ユーザー権限が制限された別の AppDomain にアセンブリを読み込みます (異なる原則)。シリアライゼーション/デシリアライゼーションなどの操作を実行できませんでした。

Assembly.LoadFrom - 同じユーザー権限 (同じ原理) で同じ AppDomain にアセンブリを読み込みます。

于 2012-09-15T07:19:20.740 に答える
0

私の場合、 @ にある ASP アプリケーション キャッシュを削除するだけで済みましたC:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files。サイトが最初に実行されたときに再構築されます。最初に IIS を停止してください。

これが私のためにしたような誰かに役立つことを願っています.

于 2015-07-08T23:12:35.567 に答える