Arte Abstrata

Arte Abstrata

Olá pessoal, hoje vou falar de um assunto bem interessante que pode nos ajudar bastante a sermos mais produtivos com nossas aplicações ASP.NET MVC.

Imaginem dois controllers, de Clientes e de Produtos e neles as operações mais básicas de criar um novo objeto de domínio e de editar um objeto de domínio.

Podemos concluir que teremos dois controllers semelhantes aos que estão lá no fim do post.

Vejam lá embaixo…

Viram?!

Certo, agora, não seria melhor se pudessemos ter controllers que tenha todas essas operações de CRUD parecidas com isso:

public class ClientesController : ControllerBase<Cliente, ClienteViewModel>
{
  public ClientesController(IClientes clientes) : base (clientes) { }
}

public class ProdutosController : ControllerBase<Produto, ProdutoViewModel>
{
  public ClientesController(IClientes clientes) : base (clientes) { }
}

Bem melhor não?

Não é de hoje que eu sempre me inspiro nos recursos do Ruby on Rails e tento aplica-los no ASP.NET MVC. E foi inspirado no Inherited Resources (veja mais aqui) que cheguei a uma abstração genérica de controllers de CRUD.

Nesse post vou demonstrar apenas como criar e como editar registros com um controller genérico, mas o mesmo conceito pode ser aplicado também na exclusão ou até mesmo em uma pesquisa simples.

Vamos lá.

Read the rest of this entry

Que sábado incrível!

Logo quando cheguei na porta do teatro da UNIP Tatuapé e vi a mesa cheia de crachás e os congressistas chegando senti que a organização do evento conduziu tudo com grande pofissionalismo. Excelente o trabalho desses profissionais:

As palestras foram ótimas.

O Giovanni Bassi coom sempre defendeu o Domain-Driven Design com muita propriedade, mostrando as grandes vantagens dessa arquitetura. Eu já havia presenciado a palestra dele sobre o mesmo tema nas reuniões do grupo, porém, mesmo assim ele conseguiu passar novas dicas que eu já vou aproveitar no meu trabalho.

A segunda palestra, a do Leandro Daniel, mostrou a todos como um ótimo pattern como a Inversão de Controle pode nos ajudar no nosso trabalho. Me arrisco a dizer que foi o melhor palestrante. Com bastante calma e tranquilidade ele levou sua apresentação a um nível ótimo. Parabéns Leandro!!! Gostei muito da forma que você soube levar a tua palestra.

A palestra sobre ASP.NET MVC, ministrada pelo Victor Cavalcante foi sobre um tema que eu adoro e acompanho muito, um ótimo conteúdo para os presentes. Eu ainda não conhecia o poder do T4 e tudo que ele poderia nos proporcionar. Aos congressistas que ainda não conheciam o ASP.NET MVC, tenho certeza que conheceram uma ótima ferramenta, apresentada com muita segurança pelo Victor.

A palestra do Mauricio Aniche era a que eu mais aguardava. Apesar de testes serem fáceis de se entender, sua aplicação demanda experiência e o Mauricio soube, como grande profissional que é, apresentar de forma bem clara e com um ótimos slides todas as vantagens e todos os tipos de testes. E lembrem-se, “Testem o tempo todo!”. Eu espero testar mais agora.

Além dos palestrantes, não posso deixar de citar o trabalho das pessoas acima. Trabalharam como verdadeiros produtores de eventos e fizeram um trabalho incrível. PARABÉNS! VOCÊS FORAM INCRÍVEIS!

A minha palestra chegou com muita ansiedade. Foi minha primeira palestra e queria uma palestra com bastante conteúdo e informação. Cometi algumas falhas e minha demonstração do NHibernate não foi completada devido a muitas dúvidas dos congressistas. Espero que apesar das pequenas falhas da minha palestra, tenha despertado a curiosidade dos congressistas de conhecer esse grande framewok que é o NHibernate.

Após a minha palestra veio o café. Excelente! Durante o café alguns congressistas vieram até mim com muitas dúvidas ainda sobre o NHibernate. Acho que consegui concluir meu objetivo que era mostrar como um framework de ORM ajuda no nosso trabalho.

Os slides da minha palestra estão no Slideshare e para quem quiser rever eu postei ele aqui também:

O projeto de demonstração você pode baixar clicando aqui.

Junto do projeto está o NHibernate Profiler e o SQLite Database Browser.

Parabéns aos organizadores desse grande evento feito pela comunidade, para a comunidade.

Aos congressistas, espero que tenham gostado da minha palestra e muito obrigado a todos.

Parabéns a todos nós: Organizadores, palestrantes e congressistas!

PS: O Fabio Margarito escreveu um post sobre o evento, vejam clicando aqui. Abaixo o link de algumas fotos postadas por ele:

[]´s

Já conhece o .Net Architects? Não? Então lá vai uma ótima oportunidade para conhecer.

O .Net Architects é um grupo de profissionais que trabalham com a plataforma .Net e que discutem sobre arquitetura e afins na internet e fazem reuniões presenciais periódicamente. Você se quiser, pode apresentar também algum tema para o grupo.

Entre no grupo de discução => .Net Architects no Google Grupos

Nesse sábado o Leandro Daniel irá fará ao grupo uma apresentação falando sobre o Unity, o framework de injeção de dependência da Microsoft. Para quem estiver fora de São Paulo, a apresentação será transmitida via Live Meeting e também será gravada para disponibilizarmos para quem perdeu.

Para saber mais clique aqui.

Você encontra o endereço e detalhes

de como chegar nessa página.

[]´s

, ,

Neste post vou descrever um assunto bem legal mas antes, queria deixar um recado aos que acompanham o Programando em .Net por feed. Voltei aos posts e espero que a partir de agora sem essas longas pausas.

Bom, vamos ao que interessa!

Nos últimos meses tenho trabalhado integralmente com ASP.NET 3.5, com o Adobe Flex, com o framework FluorineFx, com NHibernate, com o ASP.NET MVC, com o Unity, enfim… muitas tecnologias e tenho bastante coisa para falar. Posts interessantes estão sendo criados. Aguardem.

E hoje resolvi comentar sobre um post em que conheci um método bem legal de trabalharmos com ModelBinders do ASP.NET MVC.

Um dos patterns que na minha opinião mais combinam com o ASP.NET MVC é o a Inversão de Controle (conhecido também como IoC), mais precisamente o Injeção de Dependências (DI). Esse pattern torna nosso trabalho incrivelmente produtivo, uma aplicação extremamente elegante e uma forma de arquitetura muito funcional. Injetar minhas dependências através de construtores se tornou nas minhas aplicações algo padrão. Porém cheguei em uma sinuca de bico esses dias que me deixou confuso. “Como injetar dependência em nossos modelbinders (custom modelbinder)?”

A mágica veio de um artigo bem simples do Fredrik Kalseth. O artigo é o Constructor Injection for ASP.NET MVC Model Binders.

No caso do artigo do Fredrik Kalseth ele usa como framework de IoC o NInject, eu uso o Unity Application Block mas qualquer framework faz a mesma coisa. Eu já usei também o StructureMap onde comentei neste post, StructureMap – Uma Injeção de Dependências

Vamos imaginar um controller com uma action semelhante a essa:

public class ProdutoController : Controller
{
  [AcceptVerbs(HttpVerbs.Post)]
  public void Novo(Produto produto)
  {

  }
}

Suponha que no formulário para o cadastro de um novo produto seja postado o código da marca desse produto (através de um select). Como carregar a entidade da marca desse produto dentro do meu model binder? Vamos dar uma olhada nas variáveis dessa questãop.

Já vimos que temos uma classe em nosso modelo chamada Produto que em algum momento registramos um model binder que será responsável por fazer de um post transformá-a em uma classe concreta da entidade “Produto”. A primeira questão a se pensar para termos injeção de dependência no model binder é pensar em “quem vai resolver minhas dependências?”.

O Asp.Net MVC tem um “model binder default”. Esse model binder é bem simples e para modelos extremamente simples ele resolve nosso caso, como por exemplo uma entidade que necessite apenas de “Nome” e “Endereço”. Esse “model binder default” resolve esse problema pois é simples. Porém, no nosso caso, precisamos de um “model binder genérico” que resolva qualquer model binder que criarmos que necessite de dependências. Esse mesmo “model binder gernérico” irá receber em seu construtor o container com nossas dependências e ele mesmo irá resolve-las. Veja o exemplo de uma classe GenericBinderResolver, descrito no post do Fred:

public class GenericBinderResolver : DefaultModelBinder
{
  private readonly IUnityContainer _resolver;
  private static readonly Type BinderType = typeof(ModelBinder<>);

  public GenericBinderResolver(IUnityContainer resolver)
  {
    _resolver = resolver;
  }

  public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
  {
    Type genericBinderType = BinderType.MakeGenericType(bindingContext.ModelType);
    var binder = _resolver.Resolve(genericBinderType) as IModelBinder;

    if (null != binder) return binder.BindModel(controllerContext, bindingContext);

    return base.BindModel(controllerContext, bindingContext);
  }
}

Vejam que ele herda de DefaultModelBinder, recebe como parametro no construtor um container (no nosso caso um UnityCOntainer) e sobreescreve o método BindModel que é encarregado de resultar no nosso model binder que necessita de uma injeção de dependência no construtor. Quando uma requisição for “postada” para a action “Novo” do nosso constroller “Produto”, esse cara ai em cima que irá ser chamado para achar o model binder que irá bindar o parametro “Produto” dessa action.

Masta sobreescrevermos agora que o model binder padrão da nossa aplicação é GenericModelBinder e passarmos para ele o container do Unity.

ModelBinders.Binders.DefaultBinder = new GenericBinderResolver(_container);

Até aqui tudo bem, mas vemos que no nosso GenericBinderResolver temos um “objeto não identificado”. Quem é aquele “ModelBinder<>”?

Nossos model binders personalizados eram criados como uma implementação de IModelBinder e no método “GetValue”, criávamos nossa lógica onde faziamos do post de um formulário, uma entidade concreta. Como aqui, nosso caso é mais complexo, precisamos de um modelo de model binder que tenha uma “caracteristica” mais particular, por exemplo, a que entidade ele é responsável. Por isso temos ModelBinder<T> descrita abaixo:

public abstract class ModelBinder<T> : IModelBinder
{
  protected abstract T BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext);

  object IModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
  {
    return BindModel(controllerContext, bindingContext);
  }
}

Veja que ela tambem herda de IModelBinder, porém ela é uma classe abstrata e com um método que retorna “T”, que é definido em sua declaração. Nossos model binders personalizados agora devem ser herdados dessa classe abstrata ModelBinder<T>. Veja o exemplo abaixo:

public class ProdutoBinder : ModelBinder<Produto>
{
  private readonly IMarcaRepository _marcaRepository;

  public ImovelBinder(IMarcaRepository marcaRepository)
  {
    _marcaRepository = produtoRepository;
  }

  protected override Produto BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
  {
    var post = controllerContext.HttpContext.Request.Form;
    Produto produto = new Produto();

    produto.Marca = _marcaRepository.ObterMarcaPorId(post["Marca"]);

    return produto;
  }
}

Nesse caso, não necessitamos mais registrar o model binder, apenas registramos o GenericBinderResolver que esse se encarrega de resolver todos nossos binders que registramos agora, no container do nosso framework de inversão de controle. Veja bem, você não precisa mais registrar o model binder na classe estática ModelBinders (algo parecido com ModelBinders.Binders[typeof (Produto)] = new ProdutoBinder() ). APenas registramos o typo e sua implementação no container de IoC. Abaixo um exemplo de como eu registro o model binder no container do Unity.

  _container.RegisterType<ModelBinder<Produto>, ProdutoBinder>(new RequestContextLifeTimeManager(typeof(ModelBinder<Produto>)));

Acima fica mais claro o porquê da classe abstrata ModelBinder<T>. É apenas para especificarmos cara binder no container com sua caracteristica particular.

Vemos também que ao registrarmos no Unity o tipo e sua implementação, definimos seu tempo de vida no container com a classe “RequestContextLifeTimeManager” que não existe no Unity. É uma classe onde foi criado um tempo de vida de duração “por requisição”. A ao final de toda requisição, toda instancia existente no container definida com esse tempo de vida, é excluida do container. Mas é assunto para outro post.

Espero que o post seja útil!

[]´s

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

, , , , , ,