StructureMap - Uma Injeção de Dependências

Set 25th, 2008 | By Juliano Oliveira | Category: .net, design pattern, framework

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!

image

Nosso fomulário tem nosso monitor!

image

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:

image

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

Tags: , , , , , ,

Escrever um comentário