8

UPDATEMEF = potrebbe provare frustrazione?

Come ho trovato a MEF di lavoro in tutta la mia domanda, sto arrivando su più un più posti dove io proprio non capisco perché non è la creazione automatica di mia biblioteca quando mi aspetto che . Penso che tutto ciò ritorni a ciò che Reed stava dicendo sul fatto che il MEF avrebbe dovuto creare tutto. Quindi adesso ho una classe di lettore XML che deve usare i miei CandySettings, ma anche se la sua proprietà ICandySettings ha l'attributo [Importa], non viene importata. Innanzitutto ho scoperto che [Import] non funziona su statica, quindi l'ho modificato. Ma dopo ancora non ha funzionato. Penso che sia perché creo manualmente l'oggetto lettore XML, e quello che MEF vuole che faccia invece è [Import] il lettore XML ... il che significa che ora devo anche avere un'interfaccia per quello.

È quasi come usare IoC (o almeno per MEF), è un affare tutto o niente. Non puoi usarlo arbitrariamente solo qua e là, perché in ultima analisi, qualunque classe tu voglia iniettare le proprietà, deve anche essere creata da MEF.

Per favore correggimi se sbaglio!


Original post

Beh, non è ancora così male. :) Ma ho delle domande dopo che Reed mi ha indicato al MEF come una potenziale alternativa a IoC (e finora sembra piuttosto buona).

Si consideri il seguente modello: alt text http://bit.ly/9W0sHt

Come potete vedere, ho un App, e questa applicazione usa dei plugin (whoops, mancava quella associazione!). Sia l'app che i plugin richiedono l'utilizzo di un oggetto di tipo CandySettings, che si trova in un altro assembly.

Prima ho provato ad utilizzare il metodo ComposeParts in MEF, ma l'unico modo per farlo funzionare era di fare qualcosa del genere nel codice del plug-in.

var container = new CompositionContainer(); 
container.ComposeParts(this, new CandySettings()); 

Ma questo non ha alcun senso, perché il motivo per cui dovrei voler creare l'istanza di CandySettings nel plug-in? Dovrebbe essere nell'app. Ma se lo inserisco nel codice dell'app, il plugin non rileva magicamente come arrivare a ICandySettings, anche se sto usando [Importa] nel plugin e [Esporta] in CandySettings. EDIT (probabilmente perché dovrei chiamando ComposeParts() da App e poi passarlo il plugin?)

Il modo in cui l'ho fatto è stato quello di utilizzare di MEF DirectoryCatalog, perché questo permette il plugin, quando costruito, per analizzare tutti gli assiemi nella cartella corrente e importare automaticamente tutto ciò che è contrassegnato con l'attributo [Importa]. Quindi sembra che questo, e potenzialmente in ogni plugin:

var catalog = new DirectoryCatalog("."); 
var container = new CompositionContainer(catalog); 
container.ComposeParts(this); 

Questo funziona tutto grande, ma non posso fare a meno di pensare che questo non è come MEF era destinato ad essere utilizzato?

+0

Ricordo che vi sia delle vere e proprie limitazioni utilizzando MEF, e che il suo utilizzo previsto è stato per applicazioni come Visual Studio e così via, e quindi si deve essere sicuri che il disegno utenti con la loro ipotesi prime. In pratica diceva che "non è per tutti". http://codebetter.com/blogs/glenn.block/archive/2009/08/16/should-i-use-mef-for-my-general-ioc-needs.aspx –

+0

penso che funzionerà bene fuori , ma questa è una di quelle cose che mi aspetto di diventare un programmatore .NET ora. Ci sono tanti modi per scuoiare un gatto, e in pratica l'unico modo per scoprirlo è provare diverse opzioni. Finora, ho implementato il mio codice in MEF e Unity, ed entrambi funzioneranno, anche se non sono ancora sicuro che il modo in cui l'ho fatto in entrambi i framework sia corretto al 100%. – Dave

+0

Puoi aggiungere il messaggio di errore che ottieni da 'ComposeParts', il codice che stai utilizzando per inizializzare il tuo contenitore e il codice che stai utilizzando per le esportazioni/importazioni? –

risposta

8

Il "trucco" qui è che vuoi che MEF crei i tuoi plugin per te.

Il modo in cui si esegue questa operazione è quello di avere la vostra applicazione stessa comporre, con i tipi specificati Plugin:

class PluginRepository 
{ 
    [ImportMany(typeof(IPlugin))] 
    IEnumerable<IPlugin> Plugins { get; set; } 
} 

Se fate questo, e hanno MEF Componi la tua classe "repository", MEF costruirà gli oggetti. Quindi comporrà automaticamente quelli che li costruisce, quindi ICandySettings verrà composto senza alcun intervento per te.

Hai solo bisogno di manualmente "comporre" un oggetto se MEF non sta costruendo per voi.

+0

Ok, ci provo, grazie! Se funziona nell'app di test, il probabile risultato finale nell'app reale è sostituire il mio caricatore di plugin (quello che attualmente usa Reflection) con un codice come il tuo, giusto? – Dave

+0

@Dave: Sì. Non hai proprio bisogno di usare la riflessione. MEF rende questo estremamente semplice, molto affidabile e molto corto sul codice .... –

+0

@Reed: Ok, quindi ho avuto la mia app [Importa] la mia interfaccia plugin. La mia app utilizza anche DirectoryCatalog per cercare tutte le importazioni del gruppo. Il mio Plugin [Importa] s ICandySettings e la mia libreria CandySettings esporta tramite l'attributo [Esporta (typeof (ICandySettings))]. Ho fatto un passo attraverso il codice, e in App, ho confermato che l'oggetto CandySettings e l'oggetto Plugin vengono istanziati. Ma il costruttore del Plugin ha bisogno di CandySettings, e al momento della costruzione CandySettings non viene risolto ... è una limitazione o pensi che abbia cablato qualcosa di sbagliato? Ottengo un'eccezione nulla. – Dave