Come lavorare con Managed Extensibility Framework in C #

Il MEF (Managed Extensibility Framework) è un componente fornito con .Net Framework 4 (o successivo) e ti aiuta a creare applicazioni leggere ed estensibili adottando un'architettura simile a un plug-in ad accoppiamento lasco. Puoi sfruttare questo framework per scoprire e sfruttare le estensioni senza la necessità di alcuna configurazione. Utilizzando MEF puoi migliorare la flessibilità, la manutenibilità e la testabilità delle tue applicazioni con facilità. Quando si utilizza MEF, è possibile riutilizzare le estensioni all'interno della stessa applicazione o, anche tra le applicazioni.

MSDN afferma: "Managed Extensibility Framework o MEF è una libreria per la creazione di applicazioni leggere ed estensibili. Consente agli sviluppatori di applicazioni di scoprire e utilizzare estensioni senza necessità di configurazione. Inoltre, consente agli sviluppatori di estensioni di incapsulare facilmente codice ed evitare fragili dipendenze rigide. MEF non solo consente di riutilizzare le estensioni all'interno delle applicazioni, ma anche tra le applicazioni ".

DI, IoC e MEF

DI (Dependency Injection) è una realizzazione del principio IoC (Inversion of Control). Afferma che quando un oggetto dipende da altri oggetti, tali oggetti dovrebbero essere creati utilizzando un framework o un componente separato. Mentre IoC è la capacità di variare l'implementazione di un contratto, DI è la capacità di fornire l'implementazione necessaria quando richiesto. Tieni presente che dovresti usare i contenitori IoC quando le tue dipendenze sono statiche: se sono dinamiche, MEF è molto più utile. Fondamentalmente, i contenitori DI forniscono il supporto per la composizione degli oggetti, la gestione della durata e l'intercettazione.

Contrariamente a un tipico contenitore di inserimento delle dipendenze come Unity, NInject, Castle Windsor MEF fornisce il supporto solo per la composizione degli oggetti. MEF offre un modo per estendere i plug-in, una funzionalità per la quale i contenitori IOC tipici non forniscono supporto.

MEF è una libreria gestita inclusa come parte delle recenti versioni di .Net Framework (da .Net Framework 4 per essere più precisi) per scoprire estensioni attraverso la composizione senza la necessità di alcuna configurazione. Un componente in MEF è noto come parte. Una parte specifica le proprie dipendenze e capacità in modo dichiarativo. Queste dipendenze sono note come "Importazioni" e le funzionalità sono rappresentate tramite "Esportazioni". Notare che una parte dovrebbe avere un attributo "Esporta" menzionato.

Iniziare

Quando si lavora con MEF, è possibile utilizzare uno qualsiasi dei due approcci. Questi includono: l'approccio basato sugli attributi e quello basato sulle convenzioni. Quando si utilizza il primo, in genere si traggono vantaggio dagli attributi nel codice. Al contrario, in quest'ultimo si vorrebbe creare un insieme di regole e quindi determinare le regole che si applicano e quelle che non si applicano. In questo esempio esploreremo il primo approccio.

MEF fornisce estensibilità tramite un framework plug-in. Lo spazio dei nomi System.Composition fornisce il supporto per MEF in .Net. Per iniziare a usare MEF nella tua applicazione, dovresti includere l'assembly System.Composition come riferimento al tuo progetto.

Ora, considera la seguente interfaccia denominata ILogger fornita di seguito.

public interface ILogger

   {

       string Message { get; set; }

   }

The following classes FileLogger and DbLogger implement the ILogger interface.

[Export]

   public class FileLogger : ILogger

   {      

       public string Message

       {

           get;set;

       }

   }

[Export]

   public class DbLogger : ILogger

   {

       public string Message

       {

           get; set;

       }

   }

A prima vista potresti presumere che MEF sia come un contenitore DI. Tuttavia, sebbene MEF sembri un contenitore DI, mira principalmente all'estensibilità. In sostanza, MEF sfrutta un meccanismo di rilevamento basato sugli attributi per promuovere l'estensibilità senza la necessità di configurare i componenti. Non hai bisogno di alcuna registrazione: devi solo contrassegnare i tuoi tipi con l'attributo Export e fa tutto per te. A differenza di Unity, quando si utilizza MEF, è possibile contrassegnare le classi utilizzando gli attributi senza la necessità di registrarli singolarmente. I valori esportati vengono tutti memorizzati in un contenitore. La classe seguente mostra come creare un contenitore MEF personalizzato e memorizzare al suo interno tutte le esportazioni dalla directory in cui risiede l'assembly in esecuzione.

public static class MEFContainer

   {

       private static CompositionContainer compositionContainer = null;

       public static CompositionContainer Container

       {

           get

           {

               if (compositionContainer == null)

               {

                   var directoryCatalog =

                        new DirectoryCatalog(

                       Path.GetDirectoryName(

                       Assembly.GetExecutingAssembly().Location));

                   compositionContainer = new CompositionContainer(directoryCatalog);

               }

               return compositionContainer;

           }

       }

   }

Il frammento di codice seguente illustra come recuperare un'istanza di tipo FileLogger tramite il contenitore.

FileLogger fileLogger = MEFContainer.Container.GetExportedValue();

Allo stesso modo, per recuperare un'istanza di tipo DbLogger, puoi utilizzare il frammento di codice seguente.

DbLogger dbLogger = MEFContainer.Container.GetExportedValue();