2012-04-15 7 views
8

La mia applicazione carica tutti gli assembly di libreria situati nel suo percorso di esecuzione ed esegue metodi noti rispetto alle classi contenute.Carica un assembly in fase di esecuzione che fa riferimento all'assieme chiamante

Ora devo fare lo stesso con un assembly che fa riferimento all'assembly dell'applicazione. È possibile e ci sono implicazioni negative di cui dovrei essere a conoscenza?

Maestro Assemblea:

public abstract class TaskBase 
{ 
    public abstract void DoWork(); 
} 

LoadAssemblyFromFile("Assembly0001.dll"); 
Assembly0001.Task1.DoWork(); 

Assemblee Bambino:

public sealed class Task1: MasterAssembly.TaskBase 
{ 
    public override void DoWork { /* whatever */ } 
} 
+0

Lo faccio tutto il tempo senza problemi. L'unico trucco che ho incontrato (alcune volte in realtà) è la gestione della versione dell'assembly _master_. Se apporti modifiche a _master_ senza ricompilare i bambini, puoi incorrere in problemi bizzarri. –

+0

@ M.Babcock: Grazie. Per curiosità, che tipo di problemi? Non eseguo automaticamente l'incremento delle versioni di assembly su ricompilare. Presumo che DOVREBBE bypassare qualsiasi problema tu abbia mai incontrato. I tuoi pensieri? –

+0

Il problema più comune che ho riscontrato è che una definizione di metodo modifica la compatibilità con le versioni precedenti, anche se in altri casi ho riscontrato che il temuto "_Type_ è definito nell'eccezione _Master_ e _Master_" (dalla memoria quindi non al testo letterale, ma vicino abbastanza che tu lo riconoscerai). –

risposta

6

Sì, questo è possibile. Finché l'assembly principale non fa riferimento agli assembly figlio, si dovrebbe andare bene. Altrimenti, avrai una dipendenza circolare.

L'assembly master carica semplicemente gli assembly figlio e non ne sa nulla, tranne che implementano un'interfaccia. In questo modo, l'assembly principale non deve fare riferimento agli assembly figlio.

Non ho capito per quanto ne so. Usiamo questa tecnica con successo per determinati scenari.

+0

Grazie. Fuori dal contesto, c'è un modo per caricare gli assembly dalla memoria senza che il file assembly sia presente sul disco? Questi rilasci periodici di assemblaggio sono presenti in un database centrale e preferirei renderlo ragionevolmente difficile per gli utenti. Certo, capisco che non esiste un modo infallibile per raggiungere questo obiettivo. –

+0

Sì, avevamo app mobili del genere. Il binario dell'assembly è stato memorizzato nel database, recuperato e caricato in questo modo. Potresti fare la stessa cosa –

+0

Trovato: Assembly.Load (byte []). –

1

Nella mia esperienza non c'è niente di sbagliato in questo. Infatti, MEF utilizza questa tecnica sotto forma di AssemblyCatalog (dove le implementazioni sono nell'assembly principale) e DirectoryCatalog (dove le implementazioni di un'interfaccia si trovano in assiemi in una directory specifica).

Entrambi possono essere utilizzati insieme in un AggregateCatalog senza problemi.

0

L'unico "problema" è che non si può scrivere Assembly0001.Task1 nella vostra assemblea Maestro ma è possibile trovare il compito corretto nel montaggio caricato e richiamare quella:

var asm = LoadAssemblyFromFile("Assembly0001.dll"); 
var taskType = asm.GetTypes().FirstOrDefault(t => typeof(TaskBase).IsAssignableFrom(t)); 
var task = (TaskBase)Activator.CreateInstance(taskType); 
task.DoWork(); 

ci si può comunque è necessario aggiungere ulteriori controlli di sicurezza :)

+0

Sì, certo. La creazione di un'istanza di runtime per tipo è l'unico modo per ottenere ciò. Che tipo di controlli di sicurezza consiglieresti? L'applicazione deve assicurarsi che stia eseguendo il nostro codice (possibilmente attraverso un hash unidirezionale). Cos'altro? –

+0

Beh, in gran parte solo controlli nulli, se si vuole veramente creare una sandbox per eseguire i propri compiti, può diventare un po 'più difficile. – XIU

0

Non è stato inserito il codice del metodo LoadAssemblyFromFile ("..."), ma se si utilizza Assembly.LoadFrom() o Assembly.LoadFile() per caricare gli assembly, è necessario potrebbe ottenere InvalidCastException, MissingMethodException o altre eccezioni, specialmente se l'applicazione e l'assembly caricato fanno riferimento a un altro assembly identico. LoadFrom() e LoadFile() caricano gli assembly in un contesto di binding diverso rispetto all'applicazione. Vedere this per una spiegazione dettagliata.

Problemi correlati