Cómo trabajar con Managed Extensibility Framework en C #

El MEF (Managed Extensibility Framework) es un componente que viene con .Net Framework 4 (o más allá) y le ayuda a crear aplicaciones que son livianas y extensibles mediante la adopción de una arquitectura similar a un plugin acoplado libremente. Puede aprovechar este marco para descubrir y aprovechar las extensiones sin necesidad de ninguna configuración. Al usar MEF, puede mejorar la flexibilidad, la capacidad de mantenimiento y la capacidad de prueba de sus aplicaciones con facilidad. Al usar MEF, puede reutilizar las extensiones dentro de la misma aplicación o, incluso, entre aplicaciones.

El MSDN afirma: "Managed Extensibility Framework o MEF es una biblioteca para crear aplicaciones ligeras y extensibles. Permite a los desarrolladores de aplicaciones descubrir y utilizar extensiones sin necesidad de configuración. También permite a los desarrolladores de extensiones encapsular código fácilmente y evitar dependencias frágiles y duras. MEF no solo permite que las extensiones se reutilicen dentro de las aplicaciones, sino también en todas las aplicaciones ".

DI, IoC y MEF

DI (Dependency Injection) es una realización del principio de IoC (Inversión de control). Establece que cuando un objeto depende de otros objetos, dichos objetos deben crearse utilizando un marco o componente independiente. Mientras que IoC es la capacidad de variar la implementación de un contrato, DI es la capacidad de proporcionar la implementación necesaria cuando se solicita. Tenga en cuenta que debe usar contenedores de IoC cuando sus dependencias son estáticas; si son dinámicas, MEF es mucho más útil. Básicamente, los contenedores DI brindan soporte para Composición de objetos, Administración de por vida e Intercepción.

A diferencia de un contenedor de inyección de dependencia típico como Unity, NInject, Castle Windsor MEF solo proporciona soporte para la composición de objetos. MEF le proporciona una forma de ampliar los complementos, una función para la que los contenedores IOC típicos no son compatibles.

MEF es una biblioteca administrada incluida como parte de las versiones recientes de .Net Framework (desde .Net Framework 4 para ser más precisos) para descubrir extensiones a través de la composición sin necesidad de ninguna configuración. Un componente en MEF se conoce como parte. Una parte especifica sus dependencias y capacidades de forma declarativa. Estas dependencias se conocen como "Importaciones" y las capacidades se representan mediante "Exportaciones". Tenga en cuenta que una pieza debe tener un atributo "Exportar" mencionado.

Empezando

Al trabajar con MEF, puede utilizar cualquiera de los dos enfoques. Estos incluyen: los enfoques basados ​​en atributos y basados ​​en convenciones. Al usar el primero, normalmente aprovecharía los atributos de su código. Por el contrario, en este último, querrá crear un conjunto de reglas y luego determinar las reglas que se aplican y las que no. En este ejemplo exploraremos el primer enfoque.

MEF le proporciona extensibilidad a través de un marco de complementos. El espacio de nombres System.Composition proporciona soporte para MEF en .Net. Para comenzar a usar MEF en su aplicación, debe incluir el ensamblaje System.Composition como referencia a su proyecto.

Ahora, considere la siguiente interfaz llamada ILogger que se muestra a continuación.

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 primera vista, podría suponer que MEF es como un contenedor DI. Sin embargo, aunque MEF parece un contenedor DI, su objetivo principal es la extensibilidad. En esencia, MEF aprovecha un mecanismo de descubrimiento basado en atributos para promover la extensibilidad sin la necesidad de configurar los componentes. No necesita ningún registro, solo necesita marcar sus tipos con el atributo Exportar y lo hace todo por usted. A diferencia de Unity, cuando usa MEF, puede marcar sus clases usando atributos sin la necesidad de registrarlos individualmente. Todos los valores exportados se almacenan en un contenedor. La siguiente clase muestra cómo puede construir un contenedor MEF personalizado y almacenar dentro de él todas las exportaciones del directorio donde reside el ensamblado en ejecución actual.

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;

           }

       }

   }

El siguiente fragmento de código ilustra cómo puede recuperar una instancia de tipo FileLogger a través del contenedor.

FileLogger fileLogger = MEFContainer.Container.GetExportedValue();

De manera similar, para recuperar una instancia de tipo DbLogger, puede usar el siguiente fragmento de código.

DbLogger dbLogger = MEFContainer.Container.GetExportedValue();