Come posso caricare un assembly e tutte le sue dipendenze in fase di runtime in C# per Reflection?

StackOverflow https://stackoverflow.com/questions/59220

  •  09-06-2019
  •  | 
  •  

Domanda

Sto scrivendo un'utilità per me stesso, in parte come esercizio per imparare C# Reflection e in parte perché desidero effettivamente lo strumento risultante per uso personale.

Quello che cerco è fondamentalmente puntare l'applicazione su un assembly e scegliere una determinata classe da cui selezionare le proprietà che dovrebbero essere incluse in un modulo HTML esportato come campi.Tale modulo verrà quindi utilizzato nell'app ASP.NET MVC come inizio di una visualizzazione.

Dato che utilizzo oggetti Subsonic per le applicazioni che desidero utilizzare, questo dovrebbe essere ragionevole e ho pensato che, volendo includere cose come HTML di output diverso a seconda del tipo di dati, Reflection fosse il modo per ottenere questo risultato.

Quello che sto cercando, tuttavia, sembra essere sfuggente.Sto cercando di prendere la DLL/EXE scelta tramite OpenFileDialog come punto di partenza e di caricarla:

String FilePath = Path.GetDirectoryName(FileName);
System.Reflection.Assembly o = System.Reflection.Assembly.LoadFile(FileName);

Funziona bene, ma poiché gli oggetti generati da Subsonic sono in realtà pieni di tipi di oggetto definiti in Subsonic.dll, ecc., tali oggetti dipendenti non vengono caricati.Accedere:

AssemblyName[] ReferencedAssemblies = o.GetReferencedAssemblies();

Anche questo contiene esattamente ciò che mi aspetterei.Tuttavia, quello che sto cercando di capire è come caricare questi assembly in modo che il mio scavo nei miei oggetti funzioni correttamente.Capisco che se tali assembly fossero nel GAC o nella directory dell'eseguibile in esecuzione, potrei semplicemente caricarli con il loro nome, ma è probabile che non sia il caso per questo caso d'uso ed è il mio caso d'uso principale.

Quindi, ciò a cui si riduce è come caricare un dato assembly e tutti i suoi assembly arbitrari che iniziano con un nome file e risultano in un albero di tipi, proprietà, metodi, ecc. completamente esplorabile tramite Reflection.

So che strumenti come Reflector fanno questo, semplicemente non riesco a trovare la sintassi per arrivarci.

È stato utile?

Soluzione

Un paio di opzioni qui:

  1. Allegare a AppDomain.AssemblyResolve e farne un altro LoadFile in base all'assemblaggio richiesto.
  2. Girane un altro AppDomain con la directory come base e caricare gli assembly in quella AppDomain.

Consiglio vivamente di perseguire l'opzione 2, poiché probabilmente sarà più pulita e ti consentirà di scaricare tutti gli assemblaggi in seguito.Inoltre, considera il caricamento degli assembly nel contesto di sola riflessione se hai solo bisogno di riflettere su di essi (vedi Assembly.ReflectionOnlyLoad).

Altri suggerimenti

Ho lavorato Kent Boogaartè la seconda opzione.Essenzialmente dovevo:

1.) Implementare il ResolveEventHandler in una classe separata, ereditando da MarshalByRefObject e aggiungendo il Serializable attributo.

2.) Aggiungi la corrente ApplicationBase, essenzialmente dove si trova la dll del gestore eventi, in AppDomain PrivateBinPath.

Puoi trovare il codice su github.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top