Esses dias, estudando alguns Design Patterns (eu e o Rafael que trabalha comigo) conheci o StructureMap. Um framework para aplicarmos em nossas aplicações um pattern chamado Dependency Injection (ou apenas DI) quem tem a missão de baixar o nível de acoplamento da aplicação com e seus componentes.
Um exemplo prático!
Para você entender nosso exemplo, vou explicar o nosso objetivo! Vamos montar uma fábrica de Monitores! (Como assim?!) Pense em uma coisa que todo monitor tem? Um botão! Um botão que liga e desliga! Então, faremos uma interface de monitor com dois métodos: ligar e desligar. A partir dai cada fábrica de monitor implementa as interfaces como quiser.
PS: Desenhei um monitor no formulário. Nossos métodos retornarão cores, simbolizando o estado! Ao ligar nosso monitor Samsung a tela fica azul e ao ligar nosso monitor Lg fica vermelho. Quando desligarmos nosso nomitor Samsung nossa tela fica azul escuro e o Lg deixa a tela branca ao desligarmos. Vocês vão entender ao lerem o post todo!
Para começar, criei uma solução com um projeto Windows Form com o nome de MeuMonitor, um projeto Monitor, que será nossa interface e outros dois projetos class library: MonitorSamsung e MonitorLG!

Nosso fomulário tem nosso monitor!

Nossa classe Monitor implementa nossa interface:
namespace Monitor
{
public interface IMonitor
{
Color Liga();
Color Desliga();
}
}
E nossas classes MonitorSamsung e MonitorLG implementão o seguinte:
MonitorLG retorna Color.Red ao ligar e Color.White ao desligar.
namespace MonitorLG {
public class MonitorLG : IMonitor {
public Color Liga() {
return Color.Red;
}
public Color Desliga() {
return Color.White;
}
}
}
MonitorSamsung retorna Color.Blue ao ligar e Color.DarkBlue ao desligar.
namespace MonitorSamsung {
public class MonitorSamsung: IMonitor {
public Color Liga() {
return Color.Blue;
}
public Color Desliga() {
return Color.DarkBlue;
}
}
}
Quase tudo pronto, agora configuramos o StrucuteMap através do arquivo StructureMap.config:
<?xml version="1.0" encoding="utf-8" ?>
<StructureMap>
<Assembly Name="Monitor" />
<Assembly Name="MonitorLG" />
<Assembly Name="MonitorSamsung" />
<PluginFamily Type="Monitor.IMonitor" Assembly="Monitor" DefaultKey="MonitorSamsung">
<Plugin Type="MonitorSamsung.MonitorSamsung"
Assembly="MonitorSamsung"
ConcreteKey="MonitorSamsung" />
<Plugin Type="MonitorLG.MonitorLG"
Assembly="MonitorLG"
ConcreteKey="MonitorLG" />
</PluginFamily>
</StructureMap>
Olha nosso projeto:

O que queremos com tudo isso? Em nosso projeto, referenciamos um objeto global que referencia a interface IMonitor, o objeto “_monitor”. Esse objeto tem os métodos Liga() e Desliga(). Dá uma olhada na tela do monitor lá em cima, está vendo os RadioButtons? Ao serem clicados, eles mudam a instância de “_monitor” atravéz do StructureMap.
private void oSamsung_Click(object sender, EventArgs e) {
_monitor = StructureMap.ObjectFactory.GetNamedInstance<IMonitor>("MonitorSamsung");
}
private void oLg_Click(object sender, EventArgs e) {
_monitor = StructureMap.ObjectFactory.GetNamedInstance<IMonitor>("MonitorLG");
}
E os botões Liga e Desliga? Esses são os folgados do nosso projeto. NÃO FAZEM NADA DE DIFERENTE! Sempre fazem a mesma coisa, não havendo diferença mas manitor Samsung ou LG.
private void bLiga_Click(object sender, EventArgs e) {
MonitorTela.BackColor = _monitor.Liga();
}
private void bDesliga_Click(object sender, EventArgs e) {
MonitorTela.BackColor = _monitor.Desliga();
}
Pronto! Agora é só sair implementando várias classes: MonitorPhilips, MonitorSony, MonitorCCE, MonitorMitsubishi e configurar o StructureMap para que ele saiba dos assemblies.
O StructureMap nesse nosso caso serve como um Gerenciador de Plugin. Imagine os as implementações de IMonitor como plugins!
Mas vejam! O que eu quis demonstrar é o Design Pattern Dependency Injection onde nossa aplicação não depende de MonitorSamsung e nem de MonitorLG, baixamos o nível (de acoplamento). E acabamos criando um sistema gerenciador de plugin.
Espero que se diviram!
Download do exemplo da fábrica de monitores
StrutureMap Description
Structure Download
O post que me inspirou
[]’s
Pensamentos Recentes