2009-09-25 9 views
98

Ich schaute auf die msdn Dokumentation und ich bin immer noch ein wenig verwirrt darüber, was genau der Unterschied zwischen LoadFile und LoadFrom beim Laden einer Baugruppe ist. Kann jemand ein Beispiel oder eine Analogie liefern, um es besser zu beschreiben? Die MSDN-Dokumentation hat mich mehr verwirrt. Ist auch ReflectionOnlyLoadFrom das gleiche wie LoadFrom, außer dass es die Baugruppe nur im Reflexionsmodus lädt.Unterschied zwischen LoadFile und LoadFrom mit .NET Assemblies?

Da meine .NET Erfahrung nicht das größte ist, sind hier einige Fragen in Bezug auf die MSDN-Dokumentation mit Loadfile:

1) Was bedeutet es von LoadFile sucht Baugruppen, die die gleiche Identität haben, sind aber in unterschiedlichen gelegen Wege? Was ist die Identität (Beispiel)?

2) Es besagt, dass LoadFile Dateien nicht in den 'LoadFrom Context' lädt und keine Abhängigkeiten mit dem Ladepfad auflöst. Was bedeutet das, kann jemand ein Beispiel geben?

3) Schließlich gibt es an, dass LoadFile in diesem begrenzten Szenario nützlich ist, da LoadFrom Assemblys nicht laden kann, die die gleichen Identitäten aber unterschiedliche Pfade aufweisen; es wird nur die erste solche Assembly laden, was mich wiederum zur gleichen Frage bringt: Was ist die Assembly-Identität?

+6

Ernsthaft denke ich auch manchmal, dass MS bessere Autoren oder etwas anderes einstellen sollte, da die Sätze nicht immer verständlich sind ... – Tarik

+7

Siehe auch [* undocumentation *] (http://www.codinghorror.com/blog/2005/ 11/moving-undocumentation.html) –

+0

@ColonPanic MS kann sagen, dass alles dokumentiert ist ... aber mit einem Hilfsfaktor von zeroooo. – Legends

Antwort

80

Ist das klar?

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

bearbeiten: die Fragen zu beantworten, die Sie in Ihrer überarbeiteten Frage aufgeworfen, Sie wollen auf jeden Fall Suzanne Cook on Assembly Identity lesen.

Es gibt viele Regeln, die regeln, wie Assemblys geladen werden, und einige davon haben mit der Auflösung von Abhängigkeiten zu tun. Wenn Ihre AssemblyA von AssemblyB abhängig ist, wo sollte .NET nach AssemblyB suchen? Im Global Assembly Cache, im selben Verzeichnis, in dem es AssemblyA gefunden hat, oder irgendwo anders? Wenn er mehrere Kopien dieser Baugruppe findet, wie sollte er dann wählen, welche zu verwenden?

LoadFrom hat einen Satz von Regeln, während LoadFile einen anderen Satz von Regeln hat. Es ist schwer sich viele Gründe für die Verwendung von LoadFile vorzustellen, aber wenn Sie Reflektionen auf verschiedenen Kopien derselben Baugruppe verwenden müssen, ist es für Sie da.

+1

Ist die CodeBase identisch mit der Identität? – Xaisoft

+0

Nein, ich habe hier einfach CodeBase als eine beliebige Eigenschaft der Assembly verwendet, um zu verdeutlichen, dass die zweite Assembly-Instanz auf die "falsche" Datei (im ersten Beispiel) zeigte. Ich aktualisiere meine Antwort mit weiteren Details. –

+0

Es löscht es ein wenig, aber wie zeigen path1 und path2 auf verschiedene Kopien der gleichen Assembly auf der Festplatte bei Verwendung von LoadFrom und wenn LoadFile verwenden, zeigen Pfad1 und Pfad2 auf verschiedene Assemblys. Was ist ein Beispiel dafür, was path1 und path2 wären? Danke für Ihre Geduld. – Xaisoft

50

Von Suzanne Cook's blog:

Loadfile vs. Loadfrom

Vorsicht - das ist nicht die gleiche Sache.

Loadfrom() geht durch Fusion und kann jedoch mit selbe Identität, wenn man bereits auf einem anderen Weg zu einer anderen Anordnung weitergeleitet ist im Loadfrom Kontext geladen.

LoadFile() bindet überhaupt nicht durch Fusion - der Lader geht einfach voraus und lädt genau * was der Aufrufer angefordert hat. Es verwendet weder den Load- noch den LoadFrom-Kontext .

Also, LoadFrom() gibt Ihnen normalerweise, was Sie gefragt haben, aber nicht unbedingt. LoadFile() ist für diejenigen, die wirklich wollen, wirklich genau das, was angefordert wird. (* jedoch in v2 starten, wird Politik sowohl Loadfrom() und Loadfile() angewendet werden, so Loadfile() nicht unbedingt genau das, was war angefordert. Ebenfalls ab, in v2, wenn ein Montage mit seiner Identität ist in der GAC, wird die GAC Kopie stattdessen verwendet werden Verwenden ReflectionOnlyLoadFrom() genau zu laden, was Sie wollen -.. aber, beachten Sie, dass Baugruppen auf diese Weise ausgeführt kann nicht geladen werden)

LoadFile() hat einen Haken. Da keinen Bindungskontext verwendet, werden seine Abhängigkeiten nicht automatisch in seinem Verzeichnis gefunden. Wenn sie im Ladekontext nicht verfügbar sind, müssten Sie das AssemblyResolve-Ereignis abonnieren, um an sie zu binden.

Siehe here.

Siehe auch Choosing a Binding Context Artikel auf dem gleichen Blog.

+0

Danke, ich werde den Blog überprüfen, ich habe meinen Beitrag mit einigen Fragen in Bezug auf die msdn Dokumentation aktualisiert. – Xaisoft

+0

@Xaisoft - Suzanne Cooks Blog kommt mit der Antwort auf die Assemblies Identity wieder auf die Beine. Siehe http://blogs.msdn.com/suzcook/archive/2003/07/21/57232.aspx. Es ist im Wesentlichen ein "Assembly-Anzeigename" und dies ist etwa wie folgt: "System, Version = 1.0.3300.0, Culture = Neutral, PublicKeyToken = b77a5c561934e089" enthält also sowohl den tatsächlichen Namen der Assembly als auch ihre Versionsnummer zusammen mit anderen identifizierenden Informationen (wie PublicKeyToken usw.). – CraigTP

+0

Neugierig, ist Suzanne Cook der Reflection Guru :) – Xaisoft

5

ein Unterschied, der mir aufgefallen ist:

Assembly.LoadFile - Lädt Montage in verschiedenen AppDomain mit eingeschränkten Benutzerrechten (diffrence principel). Operationen wie Serilisierung/Deserilisierung konnten nicht durchgeführt werden.

Assembly.LoadFrom - Lädt Assembly in derselben AppDomain mit denselben Benutzerrechten (dasselbe Principel).

2

Hinweis: Wenn eine Assembly mit einem 8.3-Pfad und dann mit einem nicht-8.3-Pfad geladen wird, werden sie als verschiedene Assemblys angezeigt, obwohl sie dieselbe physische DLL sind.

32

Nach einer Menge Kopfschütteln habe ich heute Nachmittag einen Unterschied entdeckt.

Ich wollte eine DLL zur Laufzeit laden, und die DLL lebte in einem anderen Verzeichnis. Diese DLL hatte ihre eigenen Abhängigkeiten (DLLs), die auch in demselben Verzeichnis lebten.

LoadFile(): Loaded die bestimmte DLL, aber nicht die Abhängigkeiten. Wenn der erste Aufruf von der DLL zu einer dieser anderen DLLs erfolgte, wurde eine FileNotFoundException ausgelöst.

LoadFrom(): Loaded die DLL, die ich angegeben und auch alle Abhängigkeiten, die in diesem Verzeichnis lebten.

+3

Das war genau mein Problem! Ich erhalte die 'FileNotFoundException' beim Erstellen einer neuen Instanz eines Objekts, das in einer Assembly definiert ist, auf die von der Assembly verwiesen wird, die ich gerade mit' .LoadFile' geladen habe. Die Änderung in ".LoadFrom" schien das Problem zu beheben, aber ich wusste nicht warum! Danke – Connell

+1

Danke, ich hatte das gleiche Problem. –

0

In meinem Fall musste ich nur einfach den ASP-Anwendungscache löschen, der sich unter C:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files befindet. Es wird neu erstellt, wenn die Site zum ersten Mal ausgeführt wird. Stellen Sie sicher, dass Sie zuerst IIS beenden.

Hoffe das hilft jemand wie es für mich getan hat.

-1

Laut Dokumentation:

Loadfile (String): Lädt den Inhalt einer Baugruppendatei ein Dateipfad angegeben.

LoadFrom (String): Lädt eine Assembly anhand ihres Dateinamens oder Pfades.

Verwandte Themen