Qué es MEF y que te aporta
MEF es una tecnología que permite desarrollar aplicaciones extensibles. La gran ventaja que nos ofrece MEF es que no necesitamos diseñar la aplicación conociendo qué extensiones formaran parte de ella ni la implementación interna de las propias extensiones.
Por extensible nos referimos a que nuestra aplicación puede estar en producción y de forma dinámica añadir, reemplazar, eliminar las extensiones que tenemos sin necesidad ni de recompilar ni reiniciar la aplicación.
MEF viene con .NET Framework 4 en la librería:
System.ComponentModel.Composition.
MEF vs IoC Container
Aunque pueda parecer que MEF e IoC ofrecen la misma funcionalidad la diferencia consiste en que tratan de resolver problemas distintos.
El objetivo básico de un framework de IoC es el de ofrecer
desacoplamiento entre componentes y nos resuelve dependencias que
conocemos. Esto nos permite que nuestra aplicación sea modular y testeable.
En cambio, en MEF, el principal objetivo es la
extensibilidad: el desacoplamiento es una consecuencia. Sabemos que las extensiones que se vayan a implementar cumplirán un contrato pero no sabremos si sólo habrá una extensión, muchas o ninguna.
Ejemplo: Extensión IHelloWorld
Vamos a ver un ejemplo de cómo consumir nuestras extensiones con MEF. El ejemplo es muy sencillo y únicamente tenemos una aplicación de consola que consumirá extensiones que nos devuelven el mensaje Hola Mundo en el idioma definido en la extensión.
Primero declaramos en el ensamblado
Serrate.MEFDemo.HelloWorld.Interface el contrato que deben cumplir:
1 | namespace Serrate.MEFDemo.HelloWord.Interface |
4 | /// Contrato para extensiones |
6 | public interface IHelloWorld |
Posteriormente en nuestra aplicación de consola
Serrate.MEFDemo.HelloWorldApp tenemos la clase Consumer encargada de consumir, como no, las extensiones de terceros.
1 | namespace Serrate.MEFDemo.HelloWorldApp |
4 | /// Clase encargada de consumir nuestras extensiones |
9 | /// Esta lista importará las extensiones que cumplan |
10 | /// nuestros requisitos |
13 | public List<IHelloWorld> HelloWorldPlugins { get ; set ; } |
16 | /// Lectura de nuestras extensiones |
24 | foreach (var plugin in HelloWorldPlugins) |
26 | Console.WriteLine(plugin.GetMessage()); |
36 | string appDirectory = AppDomain.CurrentDomain.BaseDirectory; |
37 | DirectoryInfo extensionsDirectory = |
38 | new DirectoryInfo(appDirectory + "..\\..\\..\\extensions" ); |
41 | var catalog = new DirectoryCatalog(extensionsDirectory.FullName); |
44 | var compositionContainer = new CompositionContainer(catalog); |
45 | compositionContainer.ComposeParts( this ); |
Como podemos tener varias extensiones cumpliendo el mismo contrato, en nuestra aplicación declaramos una lista de este contrato, y la decoramos con el atributo
[ImportMany]:
2 | /// Esta lista importará las extensiones que cumplan |
6 | public List<IHelloWorld> HelloWorldPlugins { get ; set ; } |
Seguidamente podemos realizar la lectura de nuestras extensiones:
2 | /// Lectura de nuestras extensiones |
10 | foreach (var plugin in HelloWorldPlugins) |
12 | Console.WriteLine(plugin.GetMessage()); |
En el método Setup indicamos el directorio de nuestras extensiones y realizamos la carga de éstas:
5 | string appDirectory = AppDomain.CurrentDomain.BaseDirectory; |
6 | DirectoryInfo extensionsDirectory = |
7 | new DirectoryInfo(appDirectory + "..\\..\\..\\extensions" ); |
10 | var catalog = new DirectoryCatalog(extensionsDirectory.FullName); |
13 | var compositionContainer = new CompositionContainer(catalog); |
14 | compositionContainer.ComposeParts( this ); |
Finalmente, ya sólo nos hace falta crear nuestras extensiones que realizarán el trabajo duro. Indicaremos que las extensiones son exportables mediante el atributo
[Export]
Crearemos el ensamblado
Serrate.MEFDemo.Plugin.ES y allí tendremos nuestra clase que implementará el contrato:
1 | namespace Serrate.MEFDemo.Plugin.ES |
3 | [Export( typeof (IHelloWorld))] |
4 | public class HolaMundo : IHelloWorld |
6 | public string GetMessage() |
En otro ensamblado
Serrate.MEFDemo.Plugin.CA tendremos definida otra extensión:
1 | namespace Serrate.MEFDemo.Plugin.CA |
3 | [Export( typeof (IHelloWorld))] |
4 | public class HolaMon : IHelloWorld |
6 | public string GetMessage() |
Si colocamos las librerías de nuestras extensiones en la carpeta que espera nuestra aplicación, al ejecutarla ya nos saldrá por pantalla el resultado esperado:
> Hola Mundo
> Hola Món
En esta introducción hemos visto como utilizar MEF para que nuestra aplicación pueda ser extendida por nosotros mismos o por terceros de forma realmente sencilla.
No hay comentarios:
Publicar un comentario