2009-09-25 11 views
98

Stavo guardando la documentazione di msdn e sono ancora un po 'confuso su quale sia esattamente la differenza tra l'utilizzo di LoadFile e LoadFrom durante il caricamento di un assieme. Qualcuno può fornire un esempio o un'analogia per descriverlo meglio. La documentazione MSDN mi ha confuso di più. Inoltre, è ReflectionOnlyLoadFrom uguale a LoadFrom eccetto per il fatto che carica l'assieme solo in modalità di riflessione.Differenza tra LoadFile e LoadFrom con .NET Assembly?

Dal momento che la mia esperienza .NET non è il massimo, qui ci sono alcune questioni riguardanti la documentazione MSDN utilizzando LoadFile:

1) Che cosa significa per LoadFile esamina assemblee che hanno la stessa identità, ma si trovano in diversi percorsi? Qual è l'identità (esempio)?

2) Dichiara che lo LoadFile non carica i file nel "LoadFrom Context" e non risolve le dipendenze utilizzando il percorso di caricamento. Cosa significa questo, qualcuno può fornire un esempio?

3) Infine, lo stato LoadFile è utile in questo limitato scenario poiché LoadFrom non può caricare assiemi con le stesse identità ma percorsi diversi; caricherà solo il primo assembly di questo tipo, che mi riporta nuovamente alla stessa domanda, qual è l'identità degli assiemi?

+6

Seriamente penso anche che a volte MS dovrebbe assumere scrittori migliori o qualcos'altro visto che le frasi non sono sempre comprensibili ... – Tarik

+7

Vedi anche [* undocumentation *] (http://www.codinghorror.com/blog/2005/ 11/avoiding-undocumentation.html) –

+0

@ColonelPanic MS può dire che tutto è documentato ... ma con un fattore di aiuto di zeroooo. – Legends

risposta

80

Questo chiarisce?

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

Edit: per rispondere alle domande che sollevate in tua domanda riveduta, è sicuramente desidera leggere Suzanne Cook on Assembly Identity.

Ci sono molte regole che governano il modo in cui vengono caricati gli assiemi, e alcuni di essi hanno a che fare con il modo in cui risolvono le dipendenze - se AssemblyA dipende da AssemblyB, dove dovrebbe cercare .NET per trovare AssemblyB? Nella Global Assembly Cache, la stessa directory ha trovato AssemblyA, o da qualche altra parte interamente? Inoltre, se trova più copie di quell'assemblaggio, come dovrebbe scegliere quale usare?

LoadFrom ha un set di regole, mentre LoadFile ha un altro set di regole. È difficile immaginare molti motivi per utilizzare LoadFile, ma se è necessario utilizzare la riflessione su diverse copie dello stesso assembly, è lì per te.

+1

CodeBase è uguale all'identità? – Xaisoft

+0

No, ho appena usato CodeBase qui come proprietà arbitraria dell'assembly per illustrare che la seconda istanza Assembly puntava al file 'sbagliato' (nel primo esempio). Sto aggiornando la mia risposta con maggiori dettagli. –

+0

Si risolve un po ', ma come path1 e path2 puntano a copie diverse dello stesso assembly su disco quando si utilizza LoadFrom e quando si utilizza LoadFile, path1 e path2 puntano a diversi assembly. Qual è un esempio di cosa sarebbero path1 e path2? Grazie per la vostra pazienza. – Xaisoft

50

Da Suzanne Cook's blog:

LoadFile vs. LoadFrom

Fare attenzione - questi non sono la stessa cosa .

LoadFrom() passa attraverso fusione e può essere reindirizzato a un altro montaggio in un percorso diverso ma con stessa identità se si è già caricata nel contesto LoadFrom.

LoadFile() non esegue il binding tramite Fusion - il caricatore va semplicemente a avanti e carica esattamente * ciò che è richiesto il chiamante . Non utilizza né il carico né il LoadFrom contesto.

Quindi, LoadFrom() di solito fornisce ciò che è stato richiesto da , ma non necessariamente. LoadFile() è per quelli che davvero, vogliono davvero esattamente ciò che viene richiesto. (* Tuttavia, a partire dal v2, la politica sarà essere applicato a entrambi LoadFrom() e LoadFile(), in modo LoadFile() non sarà necessariamente essere esattamente quello che era richiesto. Inoltre, a partire dal v2, se un montaggio con la sua identità è nel GAC, la copia GAC ​​verrà utilizzata al posto Usa ReflectionOnlyLoadFrom() per caricare esattamente quello che vuoi -.. ma, nota che le assemblee caricati in questo modo non può essere eseguito)

LoadFile() ha un fermo. Dal momento che non utilizza un contesto vincolante, le sue dipendenze non sono automaticamente trovate nella sua directory. Se non sono disponibili nel contesto di caricamento, è necessario sottoscrivere l'evento AssemblyResolve all'evento per collegare ad essi.

Vedere here.

Vedere anche articolo Choosing a Binding Context sullo stesso blog.

+0

Grazie, controllerò il blog, ho aggiornato il mio post con alcune domande riguardanti la documentazione di msdn. – Xaisoft

+0

@Xaisoft - Il blog di Suzanne Cook viene di nuovo in soccorso con la risposta di un'identità delle assemblee. Vedi http://blogs.msdn.com/suzcook/archive/2003/07/21/57232.aspx. È essenzialmente un "nome di visualizzazione assembly" e questo è qualcosa come: "System, Version = 1.0.3300.0, Culture = neutral, PublicKeyToken = b77a5c561934e089" così include sia il nome effettivo dell'assembly, sia il suo numero di versione insieme ad altre informazioni identificative (come PublicKeyToken ecc.). – CraigTP

+0

Curioso, è Suzanne Cook the Reflection Guru :) – Xaisoft

5

sola differenza che ho notato è:

Assembly.LoadFile - Carichi di assemblaggio in diverse AppDomain con diritti utente limitati (diffrence principel). operazioni come la serilizzazione/deserilizzazione non possono essere eseguite.

Assembly.LoadFrom - Carica assembly nello stesso AppDomain con gli stessi diritti utente (stesso principio).

2

Nota: se un assembly viene caricato utilizzando un percorso 8.3 e quindi da un percorso non 8.3, verrà visualizzato come assembly diversi, anche se si tratta della stessa DLL fisica.

32

Dopo un sacco di grattacapi ho scoperto una differenza io stesso questo pomeriggio.

Volevo caricare una DLL in fase di esecuzione e la DLL ha vissuto in un'altra directory. Quella DLL aveva le sue dipendenze (DLL) che vivevano anche nella stessa directory.

LoadFile(): ha caricato la DLL specifica, ma non le dipendenze. Quindi, quando la prima chiamata è stata effettuata dall'interno della DLL a una di queste altre DLL, ha generato un'eccezione FileNotFoundException.

LoadFrom(): ha caricato la DLL che ho specificato e anche tutte le dipendenze che hanno vissuto in quella directory.

+3

Questo era esattamente il mio problema! Stavo ricevendo il 'FileNotFoundException' durante la creazione di una nuova istanza di un oggetto definito in un assembly a cui fa riferimento l'assembly che avevo appena caricato con' .LoadFile'. Cambiare questo in '.LoadFrom' sembrava risolvere il problema, ma non sapevo perché! Grazie – Connell

+1

Grazie, stavo avendo lo stesso problema. –

0

Nel mio caso, ho dovuto semplicemente cancellare la cache dell'applicazione ASP che si trova @C:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files. Viene ricostruito quando il sito viene eseguito per la prima volta. Assicurati di interrompere prima IIS.

Spero che questo aiuti qualcuno come ha fatto per me.

-1

Secondo la documentazione:

LoadFile (String): carica il contenuto di un file di assiemi dato un percorso di file.

LoadFrom (String): carica un assieme in base al nome o al percorso del file.