In questo periodo l’universita’ o meglio un suo laboratorio di ricerca mi ha dato l’opportunita’ (oltre che lo stimolo) di studiare MEF e le Parallel Extensions utilizzando il .NET 3.5, ed io ho colto la palla al balzo!
Cosi’ ho deciso di scrivere una serie di post su MEF sperando che possano interessare a qualcuno. Di seguito trovate la lista dei post che seguiranno nelle prossime settimane:
- Introduzione a MEF
- Imports & Exports
- Catalogs
- Recomposition
- Metadata
- Internals? “Fluent Composition”?
Cos’e’ MEF?
Il Managed Extensibility Framework (MEF) permette la creazione di applicazioni estendibili in maniera semplice e veloce evitando al programmatore di crearsi una propria infrastruttura per la gestione dei plugins.
Come funziona?
Dall’immagine sottostante possiamo notare che MEF puo’ essere “diviso” in 3 parti:
- I Catalogs (DirectoryCatalog, AssemblyCatalog, TypeCatalog, CustomCatalog) che si occupano di scovare i nostri plugins
- Il CompositionContainer che soddisfa le dipendenze ed espone gli Exports al mondo esterno
- Le Parts o meglio le Composable Parts che possono offrire dei servizi (Exports) e ne possono importare altri (Imports) da altre Composable Parts.
Una Composable Part e’ sostanzialmente l’istanza di una nostra classe che espone o utilizza dei servizi ed ogni Import/Export avra’ un determinato contratto che verra’ specificato tramite degli attributi. Il Container interagisce con i Catalogs per avere accesso alle Composable Parts e quindi risolvere le dipendenze.
Ora che abbiamo un’infarinatura molto generale di cosa sia MEF e di come funzioni diamo un’occhiata alla prima applicazione.
Abbiamo creato due progetti il primo (IntroductionToMEFSample) che contiene un’applicazione di prova, il secondo che contiene il contratto che i plugins dovreanno rispettare.
L'applicazione di prova e’ un progetto WPF dove utilizzo il pattern MVVM ed in particolare la versione implementata da Sacha Barber chiamata Cinch (in realta’ non e’ un semplice framework MVVM…infatti dentro troviamo un bel po’ di marchingegni utili). Ho utilizzato Cinch al posto di altri framework MVVM perche’ non l’avevo mai provato, quindi non uso nessuna chicca particolare.
Come possiamo vedere il MainViewModel e’ molto semplice…espone semplicemente una proprieta’ Plugin che conterra’ il plugin caricato da MEF. La proprieta’ Plugin pero’ e’ decorata con l’attributo Import che dira’ a MEF ed in particolare al CompositionContainer che deve essere valorizzata.
La classe MainViewModel invece e’ decorata con l’attributo Export che dice al CompositionContainer che il MainViewModel e’ l’implementazione di un servizio.
Passando alla MainWindow vediamo che implementa una proprieta’ ViewModel decorata anch’essa con l’attributo Import.
Di seguito troviamo l’implementazione di un plugin che implementera’ l’interfaccia IPlugin, cioe’ il contratto da noi definito. In questo caso con l’attributo Export abbiamo anche specificato il tipo da esportare, o meglio il tipo di servizio che offre la nostra Composable Part.
Togliendo il typeof(IPlugin) e lasciando un semplice Export il CompositionContainer non sara’ in grado di risolvere le dipendenze.
Passiamo ora alla parte fondamentale…come fa MEF a capire a chi associare cosa?
Nel costruttore della view abbiamo creato il CompositionContainer passandogli come parametro un AssemblyCatalog (che tratteremo nei prossimi post) al quale abbiamo passato l’assembly corrente, in quanto all’interno del nostro progetto abbiamo il plugin che vogliamo ed inoltre il ViewModel della view
Infine abbiamo chiamato l’extension method ComposeParts passandogli l’istanza della nostra classe (anch’essa e’ una ComposablePart in quanto utilizza dei servizi cioe’ il ViewModel). Il ComposeParts risolvera’ le dipendenze (in realta’ se ne occupa il metodo Compose del container) ed avremo il nostro progetto bello e funzionante.