2010-04-15 19 views
9

Sto cercando di aggiungere plug-in per il mio gioco e quello che sto cercando di attuare è questo:Come implementare correttamente i plugin in C#?

  • plugin sarà o mio o terzo partito quindi vorrei una soluzione in cui crash del plugin sarebbe non significa arresto anomalo dell'applicazione principale.

  • I metodi dei plugin sono chiamati molto spesso (ad esempio a causa del disegno di oggetti di gioco).

Quello che ho trovato finora:

la prego di commentare i miei risultati? Nuovi approcci sono anche benvenuti! Grazie!

risposta

9

È possibile definire un'interfaccia pubblica che deve essere implementata dal plug-in. Quindi con l'uso della reflection è possibile scansionare una cartella "plugin" per qualsiasi classe che implementa quell'interfaccia, quindi creare un'istanza di quella classe.

Dal tuo codice basta lavorare sull'interfaccia e chiamare il metodo necessario. A proposito di crash, assicurati sempre che le chiamate all'interfaccia "plugin" siano sempre incapsulate in un blocco try/catch. Se si verifica un'eccezione si può sempre disporre il plugin

+0

Grazie, stai parlando del mio punto 1) che utilizza piuttosto lo stesso come hai detto tu. Stavo pensando anche a try/catch blocks (http://stackoverflow.com/questions/52312/what-is-the-real-overhead-of-try-catch-in-c - non è necessario un overhead significativo). –

+0

@MartyIX Normalmente la procedura migliore è evitare di utilizzare i blocchi try/catch per le operazioni "normali". Ma dal momento che non hai alcun controllo sul codice del plugin non puoi fidarti di esso al di fuori di un blocco try/catch. – Jasper

1

Il "secrect" generalizzato di estensibilità NET è: Il caricamento dinamico (per ottenere il plugin nel dominio di applicazione), Reflection (per verificare che supporta i metodi/interfaccia specificata) , Attributi (per ottenere Meta-Dati per cose come il versioning), Late Binding (per usare effettivamente il plugin).

Se le vostre esigenze di estensibilità sono molto semplici o molto uniche, dovreste considerare l'implementazione a modo vostro.

1

Ho utilizzato this tutorial come base per la mia architettura plug-in un paio di anni fa.Credo che l'architettura fosse un'architettura relativamente semplice, ma ho riscontrato alcuni problemi quando si trattava di passare messaggi tra i plug-in.

Se sei intento a scrivere la tua architettura, allora è abbastanza giusto, ma vorrei mettere in guardia contro di esso. Non è un'impresa da poco, e prima o poi ti imbatterai in alcune importanti considerazioni di progettazione, come il passaggio di messaggi, che non sono banali da risolvere (ammesso che siano simultaneamente abbastanza interessanti e frustranti). C'è un enorme valore nell'usare qualcosa come MEF che risolve questi problemi per te, e fornisce una API e una struttura davvero belle su cui puoi costruire i tuoi plug-in.

Inoltre, MEF finirà per essere distribuito come parte della vostra applicazione, quindi non è necessario che i vostri utenti lo scarichino separatamente; è una dipendenza "invisibile" per quanto riguarda loro, e una leggera per gli sviluppatori, incluso te stesso. È anche l'architettura plug-in ufficiale per Visual Studio 2010, quindi ha un sacco di peso nella comunità .NET, e ci saranno sempre più sviluppatori in grado di scrivere plug-in per la tua app se lo usi anche tu.

Spero che abbia un senso.

+0

Grazie per il link! Beh, la comunicazione tra i plugin potrebbe essere un problema, ma il mio gioco non è così complicato (spero :)). Penserò a MEF. –

2

ho sospetta che il duplice esigenza di:

  1. prestazioni veloci con oggetti di disegno e
  2. un incidente plugin non potrebbe andare in crash la vostra applicazione

stanno per conflitto.

Per assicurarti che un plug-in con bug non blocchi la tua app, devi caricarla in un AppDomain separato (come hai già identificato). Ma stai andando a prendere un colpo di prestazioni, come l'intero punto di AppDomains è che isolano le istanze di oggetti. Quindi, come minimo, devi serializzare argomenti ai tuoi plugin (possibilmente utilizzando oggetti MarshalByRef o Remoting). E sospetto che ciò significherà serializzare una buona parte del tuo stato di gioco (che sembra almeno una specie di immagine). Sul lato positivo, AppDomains vive nello stesso spazio del processo, quindi il sovraccarico non è così grave come la comunicazione tra processi.

Scaricare i plug-in è semplice come scaricare AppDomain.

Poiché è necessario serializzare gli argomenti, è possibile eseguire la convalida dello stato del gioco dopo che il plug-in è stato elaborato.

Ho fatto un po 'di giocherellare con AppDomains una volta. Ci vogliono alcuni secondi per costruirne uno, nella mia esperienza. Ciò potrebbe influire sul numero di plug-in che carichi in ogni AppDomain.

+0

Grazie per il tuo commento! Sembra troppo sovraccarico per la mia applicazione. Usare un AppDomain con i blocchi try/catch come suggerito da Jasper sembra essere buono per il mio gioco. –

Problemi correlati