.NETアセンブリでのLoadFileとLoadFromの違いは何ですか?


126

私は、MSDNのドキュメントを見ていたと私はまだ正確に使用した場合の違いは何かに混乱少しだLoadFileLoadFromアセンブリをロードするとき。誰かがそれをよりよく説明するための例やアナロジーを提供できますか?MSDNのドキュメントは私をさらに混乱させました。また、リフレクションモードでのみアセンブリをロードすること以外ReflectionOnlyLoadFromは同じLoadFromです。

私の.NETエクスペリエンスは最高ではないので、LoadFileを使用したMSDNドキュメントに関するいくつかの質問を次に示します。

1)LoadFile同じIDを持つが、異なるパスにあるアセンブリを調べるとはどういう意味ですか?アイデンティティとは何ですか(例)?

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

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


10
真剣に私は時々、文章が常に理解できるとは限らないので、MSはより優れたライターや何か他のものを雇うべきだと思うこともあります...
Tarik


1
@ColonelPanic MSはすべてが文書化されていると言えますが、zerooooのヘルプファクターがあります。
Legends

回答:


96

これで解決しましたか?

// 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);

編集:改訂された質問で提起された質問に答えるために、アセンブリアイデンティティに関するスザンヌクックを必ず読んでください。

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

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


2
CodeBaseはIdentityと同じですか?
Xaisoft 2009

いいえ、ここではCodeBaseをアセンブリの任意のプロパティとして使用して、2番目のAssemblyインスタンスが(間違った)ファイルを指していることを示しました(最初の例)。回答を詳細に更新しています。
ジェフスターナル

1
少しクリアされますが、LoadFromを使用する場合、およびLoadFileを使用する場合、path1とpath2は異なるアセンブリを指すので、path1とpath2はディスク上の同じアセンブリの異なるコピーをどのように指しますか。path1とpath2の例は何ですか?お待ち頂きまして、ありがとうございます。
Xaisoft 2009

なぜ2つの文字列参照で値の等価性をチェックするのstring.Compare(x, y) == 0ですか?あなたはx == yそこに欲しいと思いますか?あいまいな理由で、カルチャーに依存した同等性チェックが必要な場合はstring.Equals(x, y, StringComparison.CurrentCulture)、たとえばを書く方が明確です。
Jeppe Stig Nielsen 2014

「アセンブリアイデンティティのスザンヌクック」の@JeffSternalリンクはここで壊れているようです...
Martin Verjans

61

以下からのスザンヌ・クックさんのブログ

LoadFileとLoadFrom

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

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

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

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

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

こちらをご覧ください

同じブログのバインディングコンテキストの選択に関する記事もご覧ください。


おかげで、私はブログをチェックし、msdnドキュメントに関するいくつかの質問で私の投稿を更新しました。
Xaisoft 2009

@Xaisoft-Suzanne Cookのブログが、Assemblies Identityの答えで再び助けになりました。blogs.msdn.com/suzcook/archive/2003/07/21/57232.aspxを参照してください。これは基本的に「アセンブリの表示名」で、「システム、バージョン= 1.0.3300.0、カルチャー=ニュートラル、パブリックキートークン= b77a5c561934e089」のようになっているため、アセンブリの実際の名前、バージョン番号、およびその他の識別情報( PublicKeyTokenなど)。
CraigTP 2009

1
彼女がフュージョンについて話すとき、彼女は何を指しているのですか?
Xaisoft 2009

1
確かに、ジェフはその場にいる。このリンクを参照してください:Fusionサブシステムと.NETでアセンブリをロードするためのテクノロジーに関する素晴らしいチュートリアルについては、grimes.demon.co.uk / workshops / fusionWS.htmを参照してください
CraigTP

1
上記のURL(grimes.demon.co.uk/workshops/fusionWS.htm)は無効になり、次のURLに移動しました:richardgrimes.com/workshops/fusionWS.htm
CraigTP '20

45

頭を悩ませた後、今日の午後に自分でも違いを発見しました。

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

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

LoadFrom():指定したDLLとそのディレクトリに存在するすべての依存関係をロードしました。


4
それはまさに私の問題でした!私はなっていたFileNotFoundExceptionアセンブリ私はちょうどでロードしたアセンブリで参照さで定義されたオブジェクトの新しいインスタンスを作成するとき.LoadFile。これを変更.LoadFromして問題を修正しましたが、理由がわかりませんでした!ありがとう
Connell 2013年

1
ありがとう、私は同じ問題を抱えていました。
Ivandro IG Jao 2016

4

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



0

私が気付いた1つの違いは:

Assembly.LoadFile-限られたユーザー権限(異なるプリンシパル)で異なるAppDomainにアセンブリを読み込みます。除菌・除菌などの操作ができませんでした。

Assembly.LoadFrom-同じAppDomainのアセンブリを同じユーザー権限でロードします(同じプリンシパル)。


3
これは正しくありません。Assembly.LoadFileがアセンブリを別のAppDomainにロードすると信じているのはなぜですか?
fr34kyn01535 2018年

0

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

これが私のように誰かに役立つことを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.