É uma nova biblioteca que foi introduzida no .NET Framework 4.0 que ajuda o desenvolvedor a construir aplicações extensíveis.

O MEF permite que você especifique pontos onde sua aplicação poderá ser estendida, expondo módulos que podem ser preenchidos por componentes de terceiros ou ainda importar componentes expostos por outras aplicações.

Toda aplicação que deseja suportar “plugins”, terá que se preocupar, também, em criar toda a infra-estrutura necessária para suportá-los. Ao invés de explicitamente referenciar os componentes na aplicação, o MEF permitirá efetuar o descobrimento desses componentes de forma implícita, através de composição, gerenciando tudo o que for preciso para manter essas extensões, possibilitando que sua aplicação fique dependente de uma abstração, e não de uma implementação.

Vamos ver como isso funciona na prática!

Crie um projeto do tipo Windows Forms, adicione um TabControl com duas TabPages e nomeie as tabs “Cadastro de Cliente” e “Cadastro de Funcionários”, insira alguns Labels e Textbox para simularmos um formulário de cadastro. Seu form deverá ficar como nas Figuras 01 e 02.

 

mef_01
Figura 01

 

mef_02
Figura 02

Antes de começarmos a codificar, crie uma pasta chamada “plugins” na raiz da aplicação, ela será responsável por conter as dll´s com os futuros plugins.

Pressione a tecla F7 para entrar no modo “View Code”.

Para utilizarmos o MEF devemos fazer referência a dll System.ComponentModel, ela será responsável por fornecer classes e atributos para prepararmos nosso projeto para receber componentes “plugins”.

Conforme a listagem 01, importamos o namespace System.ComponentModel.Composition e System.ComponentModel.Composition.Hosting.

Feito isso, devemos criar nosso “ponto de entrada”, para isso criamos uma propriedade do tipo TabControl que será responsável por receber as TabPages  externas, observem que decoramos nosso atributo com Import. Este atributo define uma dependência nesta parte, ou seja, durante a composição desta parte o container irá preencher esta propriedade com um componente que satisfaça este contrato.

Listagem 01

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Windows.Forms;

namespace WinMEF
{
    public partial class Form1 : Form
    {
        [Import]
        public TabControl TabItem { get;set; }


Vamos criar agora um método que irá carregar nossos plugins.

Listagem 02 – método para carregar plugins

private void CarregaPlugin()
{
    var catalog = new DirectoryCatalog( @"../../plugins" );
    catalog.Refresh();

    if ( catalog.LoadedFiles.Count > 0 )
    {
        var container = new CompositionContainer( catalog );
        container.ComposeParts( this );

        int x = 0;

        while ( TabItem.TabPages.Count != 0 )
        {
            tabControl1.TabPages.Add( TabItem.TabPages[x] );
        }
    }
}

 

Bem, o que fizemos em nosso método foi criar um objeto catalog que com base na class DirectoryCatalog irá varrer uma pasta chamada plugin (o nome da pasta fica a critério de cada um) e irá carregar nossa dll.

Verificamos se o objeto catalog foi carregado com alguma dll, caso tenha sido adicionamos nosso catalog a um Container. A classe CompositionContainer é responsável por “mapear” os dados da dll carregada com nosso ponto de entrada assim gerando todo o código necessário para a montagem das TabPages em nosso projeto.

Feito isso apenas varremos o controle importado e verificamos se o mesmo possui alguma tab a ser incorporada no projeto, caso possua apenas incluímos a mesma no controle.

Esta é uma infra-estrutura simples, mas podemos ver através dela como o MEF tornou o processo de criação e utilização de componentes muito simples.

Vamos ver agora como criar o “plugin”.

Crie um outro projeto do tipo ClassLibrary, dê o nome de MyTabControl. Agora devemos fazer referência a duas dll´s System.ComponentModel.Composition para o MEF e System.Windows.Forms para o TabControl.

Adicione o código abaixo a class que acabamos de criar, explicarei cada parte logo abaixo.

Listagem 03 – plugin

using System.ComponentModel.Composition;
using System.Drawing;
using System.Windows.Forms;

namespace MyTabControl
{
    [Export(typeof (TabControl))]
    public class MyTabControl : TabControl
    {
        private TabPage tabPage1;
        private TabPage tabPage2;

        public MyTabControl()
        {
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            tabPage1 = new TabPage();
            tabPage2 = new TabPage();
            SuspendLayout();
            SuspendLayout();
            // 
            // tabControl1
            // 
            Controls.Add(tabPage1);
            Controls.Add(tabPage2);
            Location = new Point(0, 0);
            SelectedIndex = 0;
            Size = new Size(200, 100);
            TabIndex = 0;
            // 
            // tabPage1
            // 
            tabPage1.Location = new Point(4, 22);
            tabPage1.Name = "tabPage1";
            tabPage1.Padding = new Padding(3);
            tabPage1.Size = new Size(192, 74);
            tabPage1.TabIndex = 0;
            tabPage1.Text = "Cadastro Nota Fiscal";
            tabPage1.UseVisualStyleBackColor = true;
            // 
            // tabPage2
            // 
            tabPage2.Location = new Point(4, 22);
            tabPage2.Name = "tabPage2";
            tabPage2.Padding = new Padding(3);
            tabPage2.Size = new Size(192, 74);
            tabPage2.TabIndex = 1;
            tabPage2.Text = "Emissão de Boletos";
            tabPage2.UseVisualStyleBackColor = true;
            ResumeLayout(false);
            ResumeLayout(false);
        }
    }
}

 

O que fizemos foi, instanciar os namespaces System.ComponentModel.Composition e System.Windows.Forms. Herdamos de TabControl e decoramos nossa class com o atributo “Export”, ele faz parte de System.ComponentModel.Composition, ou seja, do MEF. Este atributo é que faz com que esta classe seja reconhecida como uma Part exportável, que depois será utilizada pelo MEF para compor uma outra parte que satisfaça um contrato, no nosso caso do tipo TabControl, ou seja, colocar esta nossa classe como um plugin em alguma outra aplicação.

Criamos também duas propriedades do tipo TabPage, que serão adicionadas em tempo de execução ao nosso projeto.

Feito isso, compile o projeto, será gerada a dll que na verdade é o nosso plugin.

mef_03

Figura 03 – dll gerada


Basta adicionarmos esta dll a nossa pasta plugin que foi criada no outro projeto e rodarmos a aplicação, o MEF se encarregará de todo o restante.

mef_04

Figura 04 – aplicação rodando e dll carregada

Bem pessoal, isso é MEF, num próximo post veremos como utilizar o MEF para criarmos aplicações estendidas para o Asp .Net MVC 2.0.

Para saber mais sobre MEF acesse http://mef.codeplex.com/