Come scaricare un assembly dall’AppDomain principale?

Mi piacerebbe sapere come scaricare un assembly che viene caricato nell’AppDomain principale.

Ho il codice seguente:

var assembly = Assembly.LoadFrom( FilePathHere ); 

Ho bisogno / voglio essere in grado di scaricare questo assembly quando ho finito.

Grazie per l’aiuto.

Non è ansible scaricare un assembly da un appdomain. Puoi distruggere le appdomain, ma una volta che un assembly viene caricato in un appdomain, è lì per la durata dell’appodain.

Vedi la spiegazione di Jason Zander su Why is not there a Assembly. Scarica il metodo?

Se si utilizza 3.5, è ansible utilizzare AddIn Framework per semplificare la gestione / chiamata a diversi AppDomain (che è ansible scaricare, scaricare tutti gli assembly). Se si utilizzano versioni precedenti, è necessario creare una nuova appdomain per scaricarla.

So anche che è molto vecchio, ma può aiutare qualcuno che sta avendo questo problema! Ecco un modo in cui ho trovato di farlo! invece di usare:

 var assembly = Assembly.LoadFrom( FilePathHere ); 

Usa questo:

 var assembly = Assembly.Load( File.ReadAllBytes(FilePathHere)); 

Questo in realtà carica il “Contenuto” del file assembly, invece del file stesso. Il che significa che NON è presente un blocco file sul file di assembly! Così ora può essere copiato, cancellato o aggiornato senza chiudere la tua applicazione o provare a utilizzare un AppDomain o un marshaling separati!

PRO: molto semplice da risolvere con un 1 Liner di codice! CONTRO: non è ansible utilizzare AppDomain, Assembly.Location o Assembly.CodeBase.

Ora devi solo distruggere tutte le istanze create sull’assieme. Per esempio:

 assembly = null; 

Non è ansible scaricare un assieme senza scaricare l’intero AppDomain. Ecco perché :

  1. Stai eseguendo quel codice nel dominio dell’app. Ciò significa che ci sono potenzialmente siti di chiamata e stack di chiamate con indirizzi che si aspettano di continuare a funzionare.

  2. Supponiamo che tu abbia gestito tutti gli handle e i riferimenti al codice già in esecuzione da un assembly. Supponendo che non hai annullato il codice, una volta liberato correttamente l’assembly, hai solo liberato i metadati e IL. Il codice JIT è ancora allocato nell’heap del caricatore del dominio dell’app (i metodi JIT sono allocati sequenzialmente in un buffer nell’ordine in cui sono chiamati).

  3. Il problema finale riguarda il codice che è stato caricato in condivisione, altrimenti formalmente conosciuto come “dominio neutrale” (check out / condiviso sullo strumento ngen). In questa modalità, il codice per un assembly viene generato per essere eseguito da qualsiasi dominio app (niente cablato).

Si consiglia di progettare la propria applicazione intorno al confine del dominio dell’applicazione in modo naturale, dove lo scaricamento è completamente supportato.

È necessario caricare gli assembly temporanei in un altro AppDomain e quando non è in uso, è ansible scaricare tale AppDomain . È sicuro e veloce.

Se vuoi avere un codice temporaneo che può essere scaricato in seguito, a seconda delle tue esigenze la class DynamicMethod potrebbe fare ciò che vuoi. Questo però non ti dà lezioni.

Ecco un buon esempio su come compilare ed eseguire dll durante il runtime e quindi scaricare tutte le risorse: http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm

So che è vecchio ma potrebbe aiutare qualcuno. Puoi caricare il file dallo stream e rilasciarlo. Ha funzionato per me. Ho trovato la soluzione QUI .

Spero che sia d’aiuto.

In alternativa, se l’assembly è stato appena caricato in primo luogo, per controllare le informazioni dell’assieme come publicKey, il modo migliore sarebbe non caricarlo, e piuttosto controllare le informazioni caricando solo il Nome Assembly in un primo momento:

 AssemblyName an = AssemblyName.GetAssemblyName ("myfile.exe"); byte[] publicKey = an.GetPublicKey(); CultureInfo culture = an.CultureInfo; Version version = an.Version; 

MODIFICARE

Se è necessario riflettere i tipi nell’assembly senza ottenere l’assembly nel dominio dell’app, è ansible utilizzare il metodo Assembly.ReflectionOnlyLoadFrom . questo ti permetterà di guardare i tipi nell’assemblaggio ma non ti permetterà di istanziarli, e non caricherà anche l’assembly in AppDomain.

Guarda questo esempio come esaltazione

 public void AssemblyLoadTest(string assemblyToLoad) { var initialAppDomainAssemblyCount = AppDomain.CurrentDomain.GetAssemblies().Count(); //4 Assembly.ReflectionOnlyLoad(assemblyToLoad); var reflectionOnlyAppDomainAssemblyCount = AppDomain.CurrentDomain.GetAssemblies().Count(); //4 //Shows that assembly is NOT loaded in to AppDomain with Assembly.ReflectionOnlyLoad Assert.AreEqual(initialAppDomainAssemblyCount, reflectionOnlyAppDomainAssemblyCount); // 4 == 4 Assembly.Load(assemblyToLoad); var loadAppDomainAssemblyCount = AppDomain.CurrentDomain.GetAssemblies().Count(); //5 //Shows that assembly is loaded in to AppDomain with Assembly.Load Assert.AreNotEqual(initialAppDomainAssemblyCount, loadAppDomainAssemblyCount); // 4 != 5 }