Managed Extensibility Framework: Un ejemplo práctico (I)!

Hace ya un tiempo os hablé de una nueva librería .NET denominada Managed Extensibility Framework (MEF). MEF forma parte de la nueva versión del CLR (4.0) que vendrá con .NET Framework 4.0 y Visual Studio 2010, y habilita escenarios de re-utilización de aplicaciones y componentes, haciendo posible que aplicaciones .NET compiladas de forma estática puedan ser compuestas de forma dinámica. Como os comentaba, MEF está pensado para escenarios en los que se está implementando aplicaciones y frameworks extensibles o bien extensiones para aplicaciones.

MEF_Diagram 

El caso es que, tal y como os comentaba en este post sobre ADO.NET Data Services, últimamente estoy cacharreando bastante con las novedades de .NET Framework 4.0 y de Visual Studio 2010…y por supuesto, he podido ver a MEF en acción. La idea de este post es mostraros un primer ejemplo sencillo de como podemos extender aplicaciones mediante MEF.

MEF al detalle

Como hemos dicho, MEF permite habilitar escenarios en el que se pueden extender aplicaciones de forma dinámica…pero, ¿cómo es posible esto? Pues añadiendo “puntos de enganche” (hooks) en las aplicaciones para extenderlas con nuevos componentes (propios o de terceros):

  • Habilitando la declaración y consumo de puntos de extensibilidad de aplicaciones.
  • En la práctica, se trata de un simple Import/Export:
    • Añadimos puntos de importación dónde queramos extender la aplicación.
    • Añadimos puntos de exportación en las extensiones.

Por supuesto, otra gran ventaja de MEF es que permite extender las aplicaciones en tiempo de ejecución (las extensiones se pueden crear de forma dinámica sin necesidad de conocer la aplicación en la que se van a aplicar, y por supuesto, no tenemos que volver a compilar), y no en tiempo de compilación por lo que no hay acoplamiento. Para que os hagáis una idea de la potencia y utilidad de MEF, sólo comentaros que Visual Studio 2010 en sí mismo utiliza MEF para poder ser extendido con nuevas capacidades.

¿Cuál sería el uso práctico de MEF?  Por ejemplo, añadir nuevos módulos a una aplicación en tiempo de ejecución (Por ejemplo: se crean unos módulos de aplicación al principio y más tarde se añaden otros):

  • Podemos ir dejando los ensamblados en un directorio y que la aplicación, gracias a MEF, esté continuamente chequeando el directorio (Composition Container) en busca de nuevos ensamblados (catálogos) y los cargue sin necesidad de tener que referenciarlos.
  • También se podría monitorizar un cierto ensamblado buscando nuevos añadidos.
image image

MEF en acción

Para evaluar MEF en acción, vamos a crear un sencillo ejemplo utilizando un proyecto de aplicación de consola. A este proyecto le añadimos un elemento de tipo class file con el siguiente código: 

using System;  

namespace Without_MEF  

 

    //Class with a property implementing the interface  

    public class Doorman  

     

        public IGreeting Greeting { get; set; }   

        public void CustomerArrived()  

         

            Greeting.SayHello();  

         

     

    //Starting point -> Public interface  

    public interface IGreeting  

     

        void SayHello();  

      

    //First public class inheriting from the public interface  

    public class HappyGreeting : IGreeting  

     

        public void SayHello()  

         

            Console.WriteLine(“Hello to all my god, happy, friends!”);  

         

     

}

Cómo veis, el código es bastante simple:

  • Definimos una interfaz IGreeting de la que hereda las clases HappyGreeting.
  • A su vez definimos una clase Doorman que tiene una propiedad Greeting de tipo IGreeting.

¿Cómo usamos estas clases habitualmente en nuestro código? Pues instanciándolas. En nuestro caso, y para la aplicación de consola, sería:

            var doorman = new Without_MEF.Doorman();  

            doorman.Greeting = new Without_MEF.HappyGreeting();  

            doorman.CustomerArrived();  

            Console.ReadKey();   

Y la salida por pantalla correspondiente es la siguiente:

image

Si utilizamos MEF, un código tan simple como el anterior se simplifica aun más. Añadimos al proyecto un nuevo elemento de tipo class file, y además necesitaremos añadir una referencia a System.ComponentModel.Composition. A este archivo de clase le añadimos el siguiente código:

using System;  

using System.ComponentModel.Composition;   

namespace WithMEF  

 

    //We decorate Doormanwith Export in order to use from an application  

    [Export]  

    public class Doorman 

         

  //We have to import IGreeting       

  [Import(typeof(IGreeting))] 

        public IGreeting Greeting { get; set; } 

        public void CustomerArrived() 

        {

             Greeting.SayHello(); 

          

      

    //The original interface 

    public interface IGreeting 

   

        void SayHello(); 

     

    //We export HappyGreeting because we want to use it 

    [Export(typeof(IGreeting))] 

    public class HappyGreeting : IGreeting 

   

        public void SayHello()

       

            Console.WriteLine(“Hello to all my god, happy, friends!”); 

       

    }

}

Como podéis ver en el código anterior:

  • Por un lado, estamos exportando la clase Doorman porque la queremos consumir en otra aplicación de forma que esta sea extendida. Para poder exportar la clase, tenemos que decorarla con el atributo [Export].
  • A su vez, dentro de Doorman estamos importando IGreeting decorando para ello la propiedad que implementa esta interfaz con el atributo [Import] en el que especificamos el tipo importado.
  • Lógicamente, tendremos que exporta HappyGreeting que implementa IGreeting decorándola con [Export] y especificando que es de tipo IGreeting.

¿Y ahora como utilizamos las características de MEF en nuestra aplicación? Pues utilizando un código tan sencillo como el siguiente:

                //Monitorizamos el ensamblado actual

                 var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());  

                //Definimos un objeto contenedor 

                var container = new CompositionContainer(catalog);  

                //Buscamos el objeto exportable en el contenedor  

                var doorman = container.GetExportedObject<WithMEF.Doorman>();  

                doorman.CustomerArrived();

Cómo veis con MEF no tenemos que instanciar los objetos, sino que:

  • Definimos uno o varios catálogos desde donde nos traeremos los objetos definidos como exportables (Doorman en nuestro caso). Estos catálogos se pueden definir a partir de monitorizar un ensamblado (llamada al GetExecutingAssembly) o un cierto directorio.
  • Definimos un objeto de tipo CompositionContainer que contiene el catálogo o catálogos que nos permiten extender la aplicación.
  • Sin más, nos traemos el objeto exportable con GetExportedObject y ya lo tenemos listo en nuestra aplicación para usarlo sin que esta sea consciente de su naturaleza : no instanciamos, luego no hay acoplamiento.

Y hasta aquí llega este primer post sobre MEF. Espero que os haya resultado interesante.

Publicado por

Juan Carlos González

Juan Carlos es Ingeniero de Telecomunicaciones por la Universidad de Valladolid y Diplomado en Ciencias Empresariales por la Universidad Oberta de Catalunya (UOC). Cuenta con más de 12 años de experiencia en tecnologías y plataformas de Microsoft diversas (SQL Server, Visual Studio, .NET Framework, etc.), aunque su trabajo diario gira en torno a SharePoint & Office 365. Juan Carlos es MVP de Office Servers & Services desde 2015 (anteriormente fue reconocido por Microsoft como MVP de Office 365 y MVP de SharePoint Server desde 2008 hasta 2015), coordinador del grupo de usuarios .NET de Cantabria (Nuberos.Net, www.nuberos.es), co-fundador y coordinador del Grupo de Usuarios de SharePoint de España (SUGES, www.suges.es), así como co-director de la revista gratuita en castellano sobre SharePoint CompartiMOSS (www.compartimoss.com). Hasta la fecha, ha publicado 8 libros sobre SharePoint & Office 365 y varios artículos en castellano y en inglés sobre ambas plataformas.

3 comentarios en “Managed Extensibility Framework: Un ejemplo práctico (I)!”

  1. Que opinas de construir software de tipo ERP con este sistema?

    Yo llevo dándole vueltas desde hace tiempo, si lo gras tener una aplicación así, hacer adaptaciones a los usuarios finales es muy fácil, ya que estas arquitecturas te lo ponen “a huevo”. Eso si, previamente debes crear una jerarquía de objectos que deben ser expuestos a tus conumidores (tu mismo, tus usuarios…) y que conformen el kernel del ERP.

    ¿Que opinas, compartimos ideas?

  2. Buenas Julio,
    Pues estoy contigo, tiene sentido construir unn ERP con MEF de forma que sea sencillo ir añadiendo de forma dinmáica nuevos módulos de funcionalidad.

    Un saludo

    JC’s

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *