Domanda

Può una classe astratta essere utilizzato come oggetto di contratto tra un 'Host' e un 'plug-in'? L'idea è che il plugin eredita il contratto (si parla di un adattatore). Siamo anche comprendere che tutti i partecipanti al quadro devono ereditare MarshalByRefObject (MBro). Quindi, questo è quello che pensavamo -

Host :

class Host : MarshalByRefObject
{
}

Contratto :

public abstract class PluginAdapter : MarshalByRefObject
{
}

Plugin :

class myPlugin : PluginAdapter
{
}

Tutti e tre esistono in ASM separati di. Il nostro ospite creerà un nuovo AppDomain per ogni plugin, e viene creata la PluginAdapter come segue:

{
    ObjectHandle instHandle = Activator.CreateInstance(
    newDomain, data.Assembly.FullName, data.EntryPoint.FullName);

    PluginAdapter adapter = (PluginAdapter)instHandle.Unwrap();
}

Modifica :. Dove data è il tipo concreto di myPlugin

Ci chiedevamo se questa implementazione del quadro avrebbe funzionato. Abbiamo visto gli articoli usando un'interfaccia (IPlugin) per la derivazione plug-in, e una classe concreta come il contratto. Tali articoli sarebbero anche dire che una classe astratta può essere utilizzato, ma non esempi di che l'attuazione data. E 'necessario che il contratto sia una classe concreta?

Modifica : In questo esempio di Richard Blewett - C # Riflessione - egli utilizza un'implementazione molto più semplice:

Contratto :

public interface IPlugIn  
{  
    // do stuff  
}

Plugin :

public class PlugIn : MarshalByRefObject, IPlugIn  
{  
}

Ora, se si utilizza una classe astratta come il contratto, il plugin non può ereditare sia il contratto e MBro. Che cosa, allora, diventa la migliore implementazione di un quadro plug scalabile. Dobbiamo andare avanti e implementare servizi remoti anche se, inizialmente, che stiamo sviluppando per utilizzo con una sola macchina? Questo progetto è destinato a diventare distribuita attraverso una rete, possibilmente attraverso Internet come bene. Semplicemente, non abbiamo ancora implementato Tcp perché stiamo cercando di ottenere le basi di un quadro plug pienamente comprese e operativo.

Ha senso per implementare Tcp servizi remoti su una singola macchina utilizzando loopback?

È stato utile?

Soluzione

Le classi astratte sono scelte migliori per questo, imho. In primo luogo perché le sue interfacce sono più difficili da versione. questo post del blog viene descritto il problema si potrebbe trovare se stessi avendo lungo la strada, se non si utilizza le classi di base. Questa regola non vale solo per i plugin, btw.

A proposito di vostro disegno ...

Plugin non dovrebbero estendersi MBro. Si dovrebbe usare il tuo Host (che dovrebbe estendersi MBro) a marshall tutte le chiamate attraverso ai vostri plugin, tra cui la gestione di eventi di plugin. E 'molto facile da caricare involontariamente una DLL plug-in nel vostro dominio di applicazione principale, se si tenta di tirare loro attraverso e utilizzare le loro deleghe.

Ad esempio, se il plugin restituisce un IEnumerable per uno dei suoi metodi, può restituire un'implementazione di IEnumerable definito nell'assieme plugin. Se che non si estende MBro il dominio di applicazione principale dovrà caricare l'assembly plug-in.


Ho caricato tre progetti che si occupano di AppDomain qui:

http: // cid -f8be9de57b85cc35.skydrive.live.com/self.aspx/Public/NET%20AppDomain%20Tests/appdomaintests.zip

Uno è con le richiamate attraverso AppDomain, il secondo è evento cross-AppDomain manipolazione, e il terzo è un esempio di plugin.

Nell'esempio plug-in, un'applicazione definisce un'interfaccia plug-in (è una demo, non le migliori pratiche!) E una serie plugin. L'applicazione carica un complessivo grezzo plugin dal disco e passa sopra al dominio applicazione plugin tramite il proxy ospitante plug, dove viene caricato. L'host plug quindi un'istanza del plugin e lo utilizza. Ma quando l'host restituisce un tipo definito nel montaggio plug-in di nuovo sopra nel AppDomain applicazione, l'assemblea plugin è caricato nel dominio principale, rendendo il tutto plug inutile.

La cosa migliore per evitare questo è di fornire una classe base astratta per i plugin che non è contrassegnato serializzabile e non si estende MBro, e per portare solo indietro primitive o tipi sigillati definite indietro attraverso il confine dal dominio plugin.

Nota: i progetti sono tutti 4.0 RC. Avrete bisogno di questo o superiore per farli funzionare. In caso contrario, si dovrà modificare i file di progetto a mano o ricostruire loro per farli correre in b2 o nel 2008.

Altri suggerimenti

in dotazione "data.EntryPoint.FullName" è il nome di tipo completo, il codice di cui sopra dovrebbe funzionare.

Tuttavia, se si sta cercando di mantenere questo tipo isolato nel proprio AppDomain, si deve fare attenzione qui. Facendo data.Assembly, ti tirare il gruppo (ed è tipi) nel tuo dominio di applicazione, causando i tipi per essere caricati nel dominio di applicazione in esecuzione ...

Si consiglia di dare un'occhiata a MAF (l'Addin quadro gestito) che è un framework di estensibilità integrato in .NET per fare Addins. E 'simile (e precedenti) di MEF (Managed Extensibility Framework) , ma ha più opzioni per quanto riguarda mantenendo plugin nel proprio dominio applicazione, tra le altre cose.

Se data.EntryPoint.FullName si riferisce al tipo di cemento myPlugin non vedo alcun motivo per cui questo non avrebbe funzionato (a meno che avere problemi di assemblaggio di carico in un altro dominio applicazione ma questo è un problema diverso).

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