quarta-feira, 10 de novembro de 2010

Conceitos de Arquitetura - Injeção de Dependência

Esse é o terceiro artigo de uma série de artigos onde apresentarei alguns conceitos de arquitetura de software utilizados no desenvolvimento de aplicações corporativas. 

Inversão de controle consiste no fluxo ou comportamento do seu código, classe ou aplicativo serem controlados ou modificados externamente. Um exemplo de inversão de controle é a programação orientada a eventos.

Nesse artigo vamos estudar a Injeção de Dependência que também é uma aplicação do conceito de inversão de controle.

A Injeção de Dependência consiste em retirar da classe a responsabilidade de conhecer ou encontrar as suas dependências, reduzindo o acoplamento, e aumentando a flexibilidade do código. A Injeção de Dependência na maioria das vezes é realizada utilizando frameworks de inversão de controle.

Mas quando a classe não conhece suas dependências ela deve estar apta a receber essa informação de alguma forma.

Os modos mais comuns de receber essa informação são no construtor, ou em uma propriedade.

Exemplo da classe “Usuario” que permite injeção de dependência por construtor (constructor injection):

public class Usuario
{
    private IEnviadorDeEmail _enviadorDeEmail;

    public Usuario(IEnviadorDeEmail enviadorDeEmail)
    {
        this._enviadorDeEmail = enviadorDeEmail;
    }
}

Exemplo da classe “Usuario” que permite injeção de dependência por propriedade (setter injection):

public class Usuario
{
    public IEnviadorDeEmail EnviadorDeEmail { get; set; }
}

Um framework muito famoso que auxilia a realizar Inversão de Controle e Injeção de Dependência é o Spring.NET (http://www.springframework.net/), que é baseado nos conceitos já consolidados do Spring (versão para Java).

Todo o funcionamento do Spring baseia-se na configuração dos objetos que são utilizados na nossa aplicação, geralmente essa configuração é feita em formato XML.

Exemplo de configuração de um objeto básico no Spring.NET:

<object id="EnviadorDeEmailPadrao" type="Namespace.EnviadorDeEmailPorSMTP, AssemblyName" singleton="true" />

Todo objeto configurado no Spring.NET que deve ser exposto para a aplicação deve possuir o atributo “id”, que é o nome que você utilizará para identificar aquele objeto. Também definimos o atributo “type”, que é o nome completo (com assembly) do tipo que será utilizado na criação do objeto quando ele for requisitado. O atributo “singleton” define que o objeto pode ser reutilizado, ou seja, apenas 1 objeto será criado, e o mesmo objeto será retornado sempre que solicitado ao Spring.NET.

Quando precisamos enviar um e-mail na nossa aplicação, basta solicitarmos ao Spring o objeto pelo id, por exemplo:

//Obtemos o contexto atual da aplicação no spring
IApplicationContext ctx = ContextRegistry.GetContext();

//Solicitamos ao contexto do spring o objeto com id EnviadorDeEmail
IEnviadorDeEmail enviadorDeEmail = (IEnviadorDeEmail) ctx.getObject("EnviadorDeEmailPadrao");

Agora, veja como ficaria a configuração do Spring realizando injeção de dependência na classe “Usuario” por construtor:

<object id="EnviadorDeEmailPadrao" type="Namespace.EnviadorDeEmailPorSMTP, AssemblyName" singleton="true" />

<object id="Usuario" type="MeuNamespaceDeNegocio.Usuario, NomeDoAssemblyDeNegocio" singleton="false">
    <constructor-arg name="enviadorDeEmail" ref="EnviadorDeEmailPadrao" />
</object>

E também por propriedade:

<object id="EnviadorDeEmailPadrao" type="Namespace.EnviadorDeEmailPorSMTP, AssemblyName" singleton="true" />

<object id="Usuario" type="MeuNamespaceDeNegocio.Usuario, NomeDoAssemblyDeNegocio" singleton="false">
    <property name="EnviadorDeEmail" ref="EnviadorDeEmailPadrao" />
</object>

Nesses exemplos, configuramos um objeto com id “EnviadorDeEmailPadrao”, que é responsável pelo envio de e-mail, e também configuramos o objeto “Usuario”, que é nossa classe de negócio da entidade Usuário. Mas ao configurar o objeto “Usuario”, através dos nós “constructor-arg” ou “property”, definimos que o objeto “EnviadorDeEmailPadrao” deve ser passado ao objeto “Usuario” no construtor, ou através da propriedade. Realizando assim, a injeção de dependência.

Agora, sempre que precisarmos instanciar um objeto da classe “Usuario”, pedimos ao Spring o objeto, conforme o código abaixo:

//Solicitamos ao contexto do spring o objeto com id Usuario
Usuario usuario = (Usuario) ContextRegistry.GetContext().getObject("Usuario");

E o objeto retornado já estará com as suas dependências preenchidas.

Embora o exemplo não tenha utilizado, é recomendável a criação de uma classe para encapsular a obtenção dos objetos do contexto do Spring.NET, desse modo, estaremos acoplando apenas uma classe do nosso projeto ao Spring, o que tornará mais fácil a migração para outro framework de injeção de dependência.

Quando precisarmos alterar nosso sistema para enviar e-mail utilizando SQL Server, podemos alterar a configuração do Spring para algo semelhante a:

<object id="EnviadorDeEmailPadrao" type="Namespace.EnviadorDeEmailPorSQLServer, AssemblyName" singleton="true" />

<object id="Usuario" type="MeuNamespaceDeNegocio.Usuario, NomeDoAssemblyDeNegocio" singleton="false">
    <property name="EnviadorDeEmail" ref="EnviadorDeEmailPadrao" />
</object>

Ou imagine que você queira parametrizar a classe “EnviadorDeEmailPorSMTP”, com as propriedades “Servidor”, “Porta”, “Usuario” e “Senha”. Após criarmos as propriedades, podemos alterar a configuração do Spring para:

<object id="EnviadorDeEmailPadrao" type="Namespace.EnviadorDeEmailPorSQLServer, AssemblyName" singleton="true">
    <property name="Servidor" value="192.168.0.10" />
    <property name="Porta" value="25" />
    <property name="Usuario" value="aplicacao1" />
    <property name="Senha" value="123456" />
</object>

<object id="Usuario" type="MeuNamespaceDeNegocio.Usuario, NomeDoAssemblyDeNegocio" singleton="false">
    <property name="EnviadorDeEmail" ref="EnviadorDeEmailPadrao" />
</object>

Isso é apenas o início das possibilidades do Spring.NET, mas essas simples funcionalidades podem ajudar enormemente na configuração da aplicação e no desacoplamento.

Conceitos de Arquitetura – Desacoplamento por Interfaces

Esse é o segundo artigo de uma série de artigos onde apresentarei alguns conceitos de arquitetura de software utilizados no desenvolvimento de aplicações corporativas. 

O desacoplamento é extremamente importante para aumentar a flexibilidade ao configurar/desenvolver uma aplicação. E isso trás muitos benefícios no futuro, uma vez que o mercado está em constante evolução e a todo o momento os usuários dos sistemas precisam de novas adequações neles.

Uma prática para aumentar o desacoplamento, é a programação com interfaces. Em programação orientada a objetos, interface é um contrato que define o que a classe deve fazer, mas não como fazer. Para aumentar o desacoplamento, quando há dependência entre classes, referenciamos as interfaces da nossa dependência, ao invés de referenciar a classe diretamente. 

Outra prática muito importante para aumentar desacoplamento é separar responsabilidades diferentes em classes diferentes. Ou seja, cada classe deve ter apenas uma responsabilidade. 

Veja abaixo um exemplo que possui uma classe que realiza o envio de e-mail utilizando um servidor SMTP, e uma classe de negócio que precisa enviar e-mail.

public class EnviadorDeEmailPorSMTP {
  …
  public void EnviarEmail(string[] destinatarios, string assunto, string corpo){
    …
    //Realiza o envio de e-mail
    …
  }
}
public class Usuario {
  …
  public void RecuperarSenha(EnviadorDeEmailPorSMTP enviadorDeEmail){
    …
    enviadorDeEmail.EnviarEmail(this.Email, assunto, corpo);
  }
}
Realizando o desacoplamento através da utilização de interfaces temos. 

public interface IEnviadorDeEmail {
  void EnviarEmail(string[] destinatarios, string assunto, string corpo);
}
public class EnviadorDeEmailPorSMTP : IEnviadorDeEmail {
  …
  public void EnviarEmail(string[] destinatarios, string assunto, string corpo){
    …
    //Realiza o envio de e-mail
    …
  }
}
public class Usuario {
  …
  public void RecuperarSenha(IEnviadorDeEmail enviadorDeEmail){
    …
    enviadorDeEmail.EnviarEmail(this.Email, assunto, corpo);
  }
}

Desenvolvendo dessa forma, a classe “Usuario” não está acoplada a uma determinada forma de envio de e-mail. 

Se quisermos criar uma classe chamada “EnviadorDeEmailPorSQLServer”, que realiza o envio de e-mail utilizando um servidor de banco de dados SQL Server. Basta que a nova classe implemente a interface “IEnviadorDeEmail”, e ela poderá ser utilizada para envio de e-mail pela classe “Usuario”. Nesse caso, é perceptível que as duas classes de envio de e-mail fazem a mesma coisa, porém de forma diferente. 

Em certas circunstâncias não é interessante realizar o envio de e-mail, como ao testarmos o comportamento da classe “Usuario”. Neste caso, poderíamos também ter uma classe chamada “FalsoEnviadorDeEmail”, que implementa a interface “IEnviadorDeEmail” mas não realiza o envio do e-mail. 

Utilizei tal exemplo por que fica clara a possibilidade das duas formas de envio de e-mail, e ainda é perceptível a necessidade de não enviar e-mail durante os testes, sem precisar entrar no mérito de testes de unidade. Mas mesmo assim não gosto do envio de e-mail utilizando SQL Server, então, se você souber de um exemplo legal, favor me informar.

Conceitos de Arquitetura – Camadas

Essa é a introdução de uma série de artigos onde apresentarei alguns conceitos de arquitetura de software utilizados no desenvolvimento de aplicações corporativas.

Para um melhor aproveitamento do conteúdo dos artigos, são recomendáveis conhecimentos prévios de:
  • Programação Orientada a Objetos
  • Linguagem de programação C#

O objetivo realmente é apenas apresentar os conceitos, recomendo que leia outros materiais para o aprofundamento no assunto.


Camadas 

O princípio de camadas é um conceito básico de arquitetura de software, muitos desenvolvedores estão familiarizados com ele. 

Tal princípio consiste em distribuir a aplicação em camadas, com responsabilidades e dependências bem definidas. 

Mas por que devemos utilizar camadas no software? 

Ao utilizar camadas no software, obtemos uma melhor organização, reduzimos o acoplamento, permitimos o reuso dos componentes e aumentamos a manutenibilidade. 

Vamos a um exemplo simples. 

Imagine uma aplicação de cadastro de clientes de uma loja, em que uma única classe, é responsável por representar a entidade “Cliente”, apresentar as informações em um formulário Windows e também persistir suas informações em banco de dados. 

Agora, surge a necessidade de criar uma aplicação Web para exibir as informações dos clientes. 

Como vamos reutilizar o código responsável por representar a entidade “Cliente” e persistir as informações no banco de dados, se estes estão atrelados ao código que apresenta as informações em um formulário Windows? 

Se aplicação estivesse dividida em camadas como:
  • Apresentação Windows – Responsável por exibir as informações do cliente em formulários Windows.
  • Negócio – Responsável por representar a entidade cliente, bem como possuir suas regras de negócio.
  • Persistência – Responsável por persistir e obter a entidade cliente do banco de dados.

Poderíamos reutilizar as camadas “Negócio” e “Persistência”, a criar uma camada de apresentação para Web. 

Ao dividir a aplicação em camadas, também devemos definir claramente as dependências entre as camadas. Nesse caso, a camada “Apresentação Web” depende da camada “Negócio”, que por sua vez, depende da camada “Persistência”.

domingo, 29 de novembro de 2009

Loading True Type fonts in Flash/Flex at runtime

UPDATE 06/01/2010
  • It doesn't use Tamarin ESC Compiler anymore.
  • You can download the source code here.
-------------------------------------------------

Currently there are two usual ways to use embedded fonts in Flash/Flex:
  • Embed the font in the application SWF.
  • Or generate SWF files with the fonts, and then load them at runtime.
But with some tricks, it's also possible to load True Type fonts in a Flash/Flex application at runtime.

Click here to open an experiment I've made that does that.

What are the advantages?
  • It's easy to use and share fonts between Flash/Flex applications.
  • RIAs like text processors, image editors and others, can use this technique to allow users to use their own fonts.
How it was done?
  1. The font file (.ttf) is loaded and parsed.
  2. The glyphs are converted and a SWF file is generated in memory.
  3. Using the class flash.display.Loader, the in-memory SWF is loaded, and the font is registered.
What I've used?
Em português:

Atualmente, há duas maneiras usuais de utilizar fontes embutidas em uma aplicação Flash/Flex:
  • Gerar o SWF da aplicação com a fonte embutida.
  • Gerar arquivos SWF para as fontes, e carregá-los dinamicamente na aplicação.
Mas com alguns truques, também é possível carregar fontes True Type no Flash/Flex em tempo de execução.

Clique aqui para abrir um experimento que desenvolvi que faz isso.

Quais as vantagens?
  • Maior facilidade na utilização de fontes compartilhadas em aplicações Flash/Flex.
  • RIAs como processadores de texto, editores de imagens e outros, poderão utilizar o carregamento de fontes True Type para permitir aos usuários a utilização de suas próprias fontes.
Como isso é feito?
  1. O arquivo da fonte (.ttf) é carregado e interpretado.
  2. Os caracteres da fonte são convertidos e um arquivo SWF é gerado na memória.
  3. Utilizando a classe flash.display.Loader é feito o carregamento desse SWF, e a fonte é registrada.
O que utilizei?

sexta-feira, 24 de julho de 2009

ASP.NET - Gráfico de Gantt

Há alguns dias atrás, eu e um colega de trabalho decidimos colocar um Gráfico de Gantt em um projeto.

Queríamos algo parecido com o gráfico do Microsoft Project.

Como não achei soluções gratuitas na web que me agradassem, iniciei o desenvolvimento de um componente de Gráfico de GANTT em ASP.NET.

Bom, estou disponibilizando o código desse componente. Escrevi o código todo em português, então é um bom material para estudo.

Está bem enxuto, adicionei apenas os recursos que eu acho úteis para exibição do relatório. É interessante adicionar outras funcionalidades, como eventos e estilos na tabela, mas não o farei por enquanto.



Faça download aqui do projeto de exemplo com o código do componente.

Para inserir o componente em uma página:

Coloque as classes dentro da pasta App_Code.

Registre o namespace no topo do arquivo .aspx.
<%@ Register Namespace="CustomControls" TagPrefix="cc" %>
Insira o componente manualmente.
<cc:GraficoGantt runat="server" ID="GraficoGantt1"></cc:GraficoGantt>

sábado, 18 de julho de 2009

ASP.NET - MessageBox

Quem já desenvolveu para Windows Forms com .NET, provavelmente já utilizou a classe MessageBox para exibir mensagens de diálogo ao usuário. Ex:
MessageBox.Show("Ocorreu um erro catastrófico, o programa será fechado.");
Porém, o conceito da plataforma ASP.NET é totalmente diferente, e nela essa classe não existe.

Então como exibir mensagens para o usuário no ASP.NET?

Por algum tempo utilizei:
ScriptManager.RegisterClientScriptBlock(Page, GetType(), "mensagem", "alert('Ocorreu um erro catastrófico durante a excluso do item.')", true);
Que nada mais é do que registrar um bloco de javascript na página, e nesse bloco chamamos a função alert passando a mensagem desejada como parâmetro.

A procura de uma solução que me agradasse mais, resolvi pesquisar por algo semelhante à classe MessageBox para ASP.NET, e encontrei algumas implementações que recebem a mensagem a ser exibida e adicionam na página os códigos necessários.

Ex de utilização:
MessageBox.show("MENSAGEM");

Aqui está a classe MessageBox que exibe mensagens utilizando a função alert. Para utilizar coloque o arquivo MessageBox.cs dentro da pasta App_Code.

Entretanto, a janela exibida pela função alert é de responsabilidade do browser, pode ter diversas formas e cores, geralmente são irritantes e não combinam com a identidade visual do sistema.

Janela de alerta do Opera 9.51

Resolvi então modificar a classe MessageBox para exibir mensagens sem a função alert.
Integrei a classe ao Framework ExtJS, adicionei também suporte aos ícones que eu desejava nas mensagens, e vejam que resultado legal:



Modos de utilização:
MessageBox.Show("Mensagem1", MessageBox.MessageType.Success);
MessageBox.Show("Mensagem2", MessageBox.MessageType.Warning);
MessageBox.Show("Mensagem3", MessageBox.MessageType.Info);
MessageBox.Show("Mensagem4", MessageBox.MessageType.Error);
Baixe aqui um projeto de exemplo, com a classe MessageBox e os arquivos do ExtJS necessários.

Manter a exibição de mensagens encapsulada na classe MessageBox simplifica o código e permite alterar facilmente o modo como todas as mensagens do projeto aparecem.

Agora é só modificar para atender melhor às suas necessidades.

quinta-feira, 16 de julho de 2009

ASP.NET - Controle DList

EDITADO EM 03/03/2010
  • Correção de falhas
  • Adicionado suporte a vários tipos de itens, cada um com um template próprio.
Sei que não tem muitas informações sobre a utilização do componente, mas quem quiser saber mais basta perguntar.


EDITADO em 03/08/2009
  • O código do componente está mais organizado.
  • Adicionado o LayoutTemplate.

Constantemente tenho necessidade de criar uma interfance com uma lista de cadastro dinâmica, conforme a imagem abaixo. Onde o número de alternativas pode variar de 1 até N.



Resolvi então criar um Custom Control, que chamei de DList (Dynamic List), uma espécie de DataList sem DataSource.

Então vamos colocar a mão na massa e criar interfaces utilizando o componente.
  1. Abra o Visual Studio 2008, e crie um novo Website, utilizando a linguagem C#.
  2. Faça download de um projeto de exemplo com as classes do componente DList aqui.
  3. Copie a pasta DList de dentro da pasta App_Code do projeto de exemplo para a pasta App_Code do seu projeto.
  4. Adicionamos então uma referência para uma dll utilizada pelas classes, clique com o botão direito sobre a solução, em seguida clique em "Add reference", localize o item "System.Design" e clique em "Ok".
Pronto, agora podemos utilizar o controle DList.
Para utilizá-lo em alguma página, registre o namespace adicionado a seguinte linha no início do arquivo .aspx
<@ Register Namespace="CustomControls" TagPrefix="cc" %>
Adicione o controle na página com a seguinte linha:
<cc:DList runat="server" ID="DList1" />
O componente suporta 3 templates:
  • LayoutTemplate, utilizado para layout do componente, coloque um PlaceHolder para determinar o local onde os itens serão adicionados;
  • ItemTemplate, utilizado para a criação de cada item;
  • SeparatorTemplate, adicionado entre os itens.
O componente possui 3 eventos:
  • ItemIndexChange, disparado sempre que há alteração na posição de um elemento, facilitando a atualização de numeradores.
  • ItemCreate, disparado sempre que um item é criado, permitindo adição de componentes dinamicamente.
  • ItemCommand, disparado sempre que um comando "borbulha" de algum componente interno.
A classe DListItem, possui uma propriedade chamada ViewStateData, que pode ser utilizada para armazenar informações no viewState do item, evitando o uso de hidden fields dentro do template.
Atualmente o controle atende às minhas necessidades, caso eu adicione novas funcionalidades ou faça modificações, postarei o código atualizado.
Estou a disposição para dúvidas, sugestões, pedidos, ou discutir abordagens para essa situação.