{tecnologia, conceitos, negócios, idéias, práticas, .NET, ruby, osx, ios e algo mais}
13/05/2010
Mais MEF galera! O assunto é polêmico e controverso, mas antes de entrar no debate "MEF é um container de DI?" vou continuar mostrando o poder do mesmo.No segundo post sobre o MEF mostrei como criar um plugin simples para um logger, apenas código. Poderia ser uma regra de negócio, algo assim.Hoje vamos compor uma interface gráfica com o MEF. É isso mesmo, vamos lá.Criarei uma aplicação WPF com apenas uma janela. Essa aplicação contém 3 StackPanel. O primeiro deles contém controles criados dentro da aplicação, controles padrão.O segundo contém UserControls carregados através do MEF. E o terceiro contém um TabControl com algumas tabs criadas dentro da aplicação e outra inserida com o MEF.O projeto WPF é este abaixo:
O código da nossa janela segue abaixo:
</tabitem> </tabcontrol> </stackpanel>
Não há nenhum mistério no código acima, e o resultado dele pode ser visto abaixo:
Como pode ser visto os plugins serão carregados pelo MEF. Então vamos criar uma nova solution que conterá nossos plugins. Serão basicamente 2 UserControls simples e um TabItem, a nova solution pode ser vista abaixo:
A imagem dos UserControls criados pode ser vista abaixo, e como são bem simples não vou colocar o código XAML aqui (estará disponível para download no final do post):
O código para os 3 plugins está abaixo:
[Export(typeof(UserControl))]
public partial class UserControl1 : UserControl{
public UserControl1() { InitializeComponent();
}
}
[Export(typeof(UserControl))]
public partial class UserControl2 : UserControl{
public UserControl1() { InitializeComponent();
}
}
[Export(typeof(TabItem))]
public class TabPlugin1 : TabItem{
public TabPlugin1() { this.Header = "Tab Plugin com MEF";
this.Content = "Content da tab carregada com MEF";
}
}
Notem na linha 1 das 3 listagens acima que estamos utilizando o atributo Export, explicado aqui neste post. As duas primeiras listagens criam UserControls que foram mostrados na figura acima. A terceira listagem cria um TabItem que é o tipo de objeto adicionado no TabControl, pois estamos criando uma tab em forma de plugin. Tudo muito simples.Agora para que tudo isso seja carregado na nossa aplicação, vamos compilar a solution dos plugins e copiar as DLLs para uma pasta na nossa aplicação WPF chamada plugins.Feito isso o código abaixo deve ser colocado no codebehinde da nossa janela wpf:
public partial class MainWindow : Window{ [ImportMany]
public List<usercontrol> pluginButtons;
[ImportMany]
public List<tabitem> tabPlugins;
public MainWindow() { InitializeComponent();
Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
void MainWindow_Loaded(object sender, RoutedEventArgs e) {
var catalog = new DirectoryCatalog("../../plugins");
catalog.Refresh();
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
foreach(var b in this.pluginButtons) this.stackPluginsContainer.Children.Add(b);
foreach(var t in this.tabPlugins) this.tabComPlugins.Items.Add(t);
}
}
</tabitem></usercontrol>
Nas linhas 4 e 6 temos duas coleções, uma de UserControl e outra de TabItem. Estas coleções é que serão compostas pelo MEF. Ambas possuem o atributo Import explicado aqui neste post. Nas linhas 19 a 21 estamos dizendo ao MEF para criar um catálogo de parts na pasta plugins e criando um container com este catálogo, então dizemos ao MEF para compôr nossa janela WPF, ou seja compôr as parts da nossa janela (as coleções de UserControl e TabItem).Por final apenas percorrermos as coleções e adicionamos cada coisa em seu lugar, os UserControls em seu StackPanel e os TabItems no TabControl.Para mais detalhes sobre cada o catálogo, o container e o processo de composição veja este post aqui.O resultado da nossa aplicação, quando pressionamos F5 é este:
Reparem nos nossos 3 plugins adicionados perfeitamente.É isso pessoal, este é mais um exemplo de como o MEF pode nos ajudar a criar aplicações plugáveis e extensíveis.Poderíamos criar telas e módulos inteiros de um sistema utilizando o MEF. Podemos criar um sistema complexo apenas plugando diversas partes deste sistema, totalmente modularizado.Poderíamos ter features fixas do sistema, coisas padrão, e distribuir outras funcionalidades de forma isolada, para alguns usuários, clientes ou para quem comprasse estas features. Tudo de forma pluggable e simples.As possibilidades são muitas, mas vale muito ficar atento e entender em quais cenários utilizar e em quais cenários não utilizar.Os fontes todos podem ser baixados aqui.Qualquer dúvida, comentário, crítica ou sugestão deixem comentários ou mandem e-mail que eu respondo =]Abraços,Vinicius Quaiato.