Arquivo para a categoria 'Engenharia de software'

Visual Studio + NHibernate: Tutorial corrigido e com fontes

Após inúmeros pedidos resolvi incrementar nosso tutorial “Visual Studio + NHibernate: Construindo aplicações em camadas“. Fiz diversas modificações visando dar mais qualidade a este material que é de grande importância para aqueles de desejam utilizar o NHibernate no desenvolvimento de sistemas de informações utilizando o Visual Studio.  Vou descrever as novidades:

  • Site do tutorial. Foi criado um site com os arquivos necessários para acompanhar o tutorial: script do banco em firebird ou arquivo de dados já criado, solução completa com fontes com os arquivos criados em cada etapa do tutorial. Agora voce pode ler o tutorial, baixar a solução e ver como ficou comparando com a sua implementação;
  • O MyGeneration deixou de ser utilizado para gerar as classes. Desenvolvemos um programa que faz esse trabalho de maneira mais rápida e prática. O programa é RSClass – Gerador de Classes. A utilização deste programa é livre sem qualquer limitação (apenas para uso não-comercial).  Dispnibilizamos também os fontes para aqueles que se interessarem. Entre em contato comigo por email e sabia como;
  • Alguns problemas no texto foram corrigidos visando dar maior claresa no entendimento do tutorial;
  • Os programas envolvidos foram atualizados (Visual Studio, Banco de dados e a novidade, RSClass).

Para aqueles que já leram sugerimos uma revisada no tutorial para ver pessoalmente o que mudou. Para os que estão acessando pela primeira vez saibam que estão desfrutando de um material que é aprimorado a medida que novas idéias e tecnologias vão surgindo.

Desde já, obrigado a todos que participam com sugestões, dúvidas e principalmente adiquirindo nossos Sistemas c/ fontes. Isso nos motiva a continuar estudando e melhorando a qualidade deste e de outros trabalhos.

É isso.

EDWS – Sistema de Gerenciamento de Conteúdo

Em certa oportunidade um usuário me pediu para construir um site para o estabelecimento onde trabalha. Eu perguntei qual o objetivo do site. Ele simplesmente respondeu que a chefia dele quem solicitou e ele não sabia nem por onde começar. Ele não tinha a menor idéia do que ia colocar no site. Fiz algumas sugestões de conteúdos e disse que ele deveria, primeiro, conversar com os setores do estabelecimento e colher informações para alimentar o site com notícias, fotos, informações, artigos, textos, etc.

Mas surgiu um problema: quem iria dar manutenção no site? EU? Sem chances!!!!!!! Foi aí que surgiu a idéia de construir um sistema gerenciador de conteúdo onde ele mesmo pudesse criar e gerenciar as páginas do site. A criação das páginas deveria ser bem simples, como se fosse um editor de textos. Procurei na Internet sistemas de CMS (Content Management System ou Sistema Gerenciador de Conteúdo) prontos que pudessem ajudar nessa tarefa e achei alguns: Blogs gratuitos, EVA (100% brasileiro), XOOPS, etc. Todos muito bons porém, para usuários com pouca ou nenhuma experiência, são exageradamente cheio de recuros. É bom que se diga, bons recursos. Mas para o meu problema, possivelmente eu tivesse que “dar um curso” de alguma dessas ferramentas para o usuário e o pior: ficar tirando dúvidas, etc. Sem falar nos problemas com a instalação do banco de dados.

Decidi construi algo mais simples, levando em consideração que o usuário só queria ter um local na Internet para divulgar informações. Construi o EDWS – Edição Dinâmica de WebSite. Esta primeira versão era bem limitada. Uma versão light. Tinha uns 3 layouts prontos, menu superior e lateral e dois recursos pré-formatados: uma página “Fale conosco” e uma outra para localização do estabelecimento no Google Maps. Adicionei também um contador de visita além de uns links para alguns serviços últeis: consulta de CEP e previsão do tempo. A edição das páginas era feita utilizando o FCK Editor. Já falei dele em posts anteriores. Documentação sobre este editor pode ser facilmente encontrado na Internet.

O fato é que o usuário ficou satisfeito e eu também. Ele fez o site e está no ar até hoje. Eu também gostei do resultado e decidi desenvolver outra versão para o EDWS. Nasce, então, o EDWS – Sistema de Gerenciamento de Conteúdo. Adicionei inúmeros outros recursos pré-formatados: blog, álbum, notícias, novos layouts, YouTube, etc.

Além de tudo, decidi disponibilizá-lo para quem desejar utilizar em seus trabalhos. Acho que o maior diferencial deste sistema é a simplicidade e facilidade de uso. Quem desejar conhecer mais sobre este sistema e baixá-lo pode acessar o blog que criei especialmente para este projeto: http://edwsblog.wordpress.com. Não há necessidade de adiquirir licença para utilizar a versão gratuita. Porém quem desejar suporte ou os fontes do programa poderá entrar em contato comigo para fazer-mos alguma negociação. A única limitação dessa versão gratuita é a exibição de um link para o blog do EDWS.

É isso!

Relatórios em .NET: ReportViewer e NHibernate

Quem utiliza sistemas de informações sabe da importância dos relatórios. Eles são tão importantes quanto o próprio banco de dados. Listagens, gráficos, resumos, sumários, formulários são alguns exemplos de resultados que essas ferramentas devem ser capazes de fornecer. Claro que dada tipo de resultado será aplicado em um contexto. Cada sistema precisa emitir relatórios de acordo com a necessidade do trabalho onde for utilizado. Por exemplo, os gráficos são normalmente utilizados para avaliação e gestão. As listagens são utilizadas para buscas, levantamentos, etc. O fato é que relatórios são de vital importância para quem utiliza algum sistema de gerenciamento de dados.

Por outro lado, os desenvolvedores de sistemas sabem da dificuldade de se construir um relatório. Isso sem falar das alterações que possam surgir posteriormente. Todos procuram alguma ferramenta que possa minimizar o desgaste natural causado pelo processo de construção e manutenção de relatórios. A situação tende a se agravar quando falamos de relatórios para sistemas web. Isso por que os navegadores trabalham com HTML. A situação natural é montar relatórios utilizando esta linguagem diretamente e isso não é tão trivial assim. Mesmo utilizando alguma outra linguagem que rode do lado do servidor o resultado final deve ser em HTML que é o que os navegadores são capazes de exibir. Para aumentar o poder desses navegadores alguns recursos podem ser utilizados: ActiveX, Plugins, Flash, Applets, etc. Essas e outras tecnologias, além de dar maior poder aos navegadores, aumentam a produtividade dos desenvolvedores já que podem utilizar ferramentas mais completas para gerar os relatórios que serão vistos nos navegadores.

Em .NET não seria diferente. Montar relatórios é um processo muito delicado. A pergunta é qual a melhor forma? Qual a melhor ferramenta? Resposta: EU NÃO SEI. Mas será que existe uma forma dita “melhor”?! Mas, como todo programador, eu também tenho a minha forma que pode não ser a melhor nem a mais ortodoxa. Mas é a minha forma e é com ela que tenho resolvido a maioria dos problemas. Vou compartilhar com voces.

A minha primeira experência em .NET foi quando eu tive que migrar um sistema do Delphi para o Visual Studio 2003. Neste sistema existe inúmeros relatórios. Inicialmente fiz as telas de usuário. Como o sistema em delphi utiliza as procedures de banco como regras de negócio não tive muitos problemas. Tive apenas que refazer as telas que iriam chamar as procedures. O problema começou na hora dos relatórios. Inicialmente tentei utilizar o Crystal Reports. Não me identifiquei com ele. Achei muito complicado e etc. A primeira solução que me veio a cabeça foi a seguinte: já que os relatórios estavam todos prontos em Delphi utilizando views e procedures do banco de dados decidi criar em Delphi um servidor de relatórios. O funcionamento era +ou- assim:

  1. Um programa executavel criado em delphi e instalado no servidor encapsulava todos os meus relatórios. Este programa tinha a capacidade de exportar relatórios em PDF para a pasta web da minha aplicação.
  2. Este programa era chamado de dentro da minha aplicação asp.net passando alguns parâmetros:  id-relatorio, arq-pdf-saida, param-1, param-2, … , param-n. O id-relatório identificava o relatório que eu gostaria de imprimir. Os parêmetros, de 1 a n, eram passados de acordo com a necessidade da instrução SQL do relatório.
  3. O programa recebia estes parêmtros, conectava-se ao banco, extraia os dados do banco, montava o relatório e exportava para pdf em uma pasta com nome e path indicado pelo arq-pdf-saida.
  4. A aplicação aguardava o término do processo até um certo limite e redirecionava o browser para o arquivo pdf gerado. Com o Adobe Reader instalado o navegador baixava este pdf e exibia ao usuário.

Durante muito tempo este sistema funcionou assim. Principalmente por que eu não tinha muito tempo para refazer toda aplicação inclusive os relatórios em 100% .NET utilizando o Crystal.

Mas, novas versões deste sistema foram surgindo e com elas, a necessidade de utilizar uma forma 100% .NET de fazer relatórios. Fiz algumas buscas e achei algumas ferramentas muito interessantes:

  1. DevExpress
  2. Afalinasoft
  3. StimulSoft
  4. PerpetuumSoft
  5. (…)

Algumas eu testei e gostei. Todas são muito boas e integradas ao IDE do Visual Studio. Cada uma com suas características e diferenciais. Mas todas tem a principal limitação para o tipo de trabalho que eu faço:  não são gratuitas. Porém nada impede de utilizar a versão demo convivendo com algumas situações. Uma coloca o nome DEMO no meio de cada página impressa. Outra limita o número de páginas impressas. Outra coloca uma pequena propaganda no final da página. Enfim…. Pra mim era inviável.

Há também quem prefira fazer relatórios em HTML para exibir diretamente no navegador. Separei também um link para esses programadores: http://www.webly.com.br/tutorial/net/8861/aspnet-gerar-relatorio-em-html.htm.

Foi quando eu conheci o ReportViewer. Estudei um pouco sobre ele. Dê uma olhada nos endereços abaixo e conheça também um pouco mais:

  1. http://www.macoratti.net/aspn_grv.htm
  2. http://www.devmedia.com.br/articles/viewcomp.asp?comp=5371
  3. http://blog.adsystems.com.br/2009/04/10/tutorial-c-relatorios-master-detail-com-reportviewer/
  4. http://www.macoratti.net/08/03/vbn5_rpv.htm
  5. http://www.macoratti.net/08/03/vb8_rpv2.htm
  6. http://csharpbrasil.com.br/2008/09/11/criando-relatorio-com-reportviewer-em-aspnet/

Não vou entrar em detalhes do funcionamento. Os links acima são bem explicativos.  Mas duas novas questões surgem:

  1. Eu não gostaria de utilizar o visualizador padrão do ReportViewer. Gostaria de exportar os relatórios diretamente para pdf para utilizar o Adobe Reader como visualizador no prórprio navegador.
  2. Gostaria da utilizar o NHibernate como minha fonte de dados também. O natural é conectar o banco com algum DataSource. Gostaria que os dados viessem da minha camada de negócio (BO) e não conectando diretamente o banco. Principalmente pelo fato da independência de dados que já comentei e posts anteriores.  Sem falar no fato de obedecer as regras da arquitetura em camadas.

Graças a Deus, consegui resolver os dois problemas. Não pretendo construir um tutorial para cada solução.Vou passar a idéia da solução. A implementação da proposta fica como exercício para o leitor.  É necessário ter conhecimento intermediário de OOP, persistência com NHibernate, Visual Studio e arquitetura em camadas. Em posts atenteriores dou uma ajuda nessas questões. Vale a pena dar uma olhada.

Vamos ao que interessa.

  1. Os relatórios desenvolvidos com ReportViewer podem ter como fonte de dados os DataTables. Esses DataTables podem ser criados tanto em tempo de execução quanto em tempo de desenvolvimento. Para nossa proposta é legal criá-los em tempo de desenvolvimento. Isso irá facilitar a confecção do arquivo de relatório (.rdlc). Faça isso. Abra um projeto no VS e adicione um item DataSet. Neste DataSet adicione um DataTable. As colunas do DataTable serão os campos que vc irá imprimir. Adicione as colunas com seus respectivos nomes.
  2. Adicione um novo item ao seu projeto. Este item deve ser um Report (.rdlc). Agora voce deverá formatar o relatório de acordo com sua necessidade. Os links acima dão uma ideia de como trabalhar com a IDE. Uma coisa importante: as colunas do seu relatórios devem ser vindas do DataTable que voce criou no item anterior. Mas para que seja possível fazer essa associação voce deve vincular o relatório ao DataTable. No menu Report, selecione o DataSource. Na caixa suspenda selecione o DataTable que voce criou indicando-o como fonte de dados do relatório. A partir daí voce já pode adicionar colunas ao seu relatório.
  3. Talvez vc queria indicar algumas informações no cabeçalho do seu relatório, tais como: nome da empresa, período, setor, etc. Isso deverá ser passado ao relatório através de parâmetros. No menu Report->Report Parameters voce pode indicar todos os parêmetros que desejar e posicioná-los no cabeçalho do relatório.

Neste relatório voce pode definir: grupos, sumários, totais, gráficos, tabelas com números de linhas e colunas variáveis, etc. Consulte documentação do ReportViewer.  Com um pouco de prática tudo vai parecer muito natural. No início eu támbem demorei um pouco a me familiarizar com o ambiente. Há quem diga que no ReportViewer não dá pra fazer relatórios muito complexos. Para os relatórios do dia a dia tenho tido ótimos resultados. Sem falar no fato: ReportViewer é uma solução gratuita. Qualquer relatório mais complexo que sua empresa precise, posivelmente tenha que meter a mão no bolso. ;)

Mas, continuando… A questão agora é o Nhibernate. Sem problemas! No seu DAO e/ou BO voce deve ter um método que retorne para a camada de apresentação os dados que prentende utilizar no relatório. Esses dados podem ser retornados de diversas formas: IList, IList<> ou o próprio DataTable, inclusive utilizando a estrutura definida no DataSet/DataTable do relatório. Não aconselho usar DataTable nas camadas BO e DAO para retornar dados. Surigo utilizar sempre IList<> nessas camadas e deixar pra conversão em DataTable na camada de apresentação utilizando algum foreach. (Já notou que eu uso C#, não é?) O DataTable destino será aquele mesmo que formatou o relatório do ReportViewer.  Associe o DataTable o relatório, preencha os campos de parâmetros e mande exibir. Vc pode seguir um dos tutoriais que indico acima.

Mas se vc não quiser utilizar o visualizador padrão do ReportViewer? Eu sempre exporto o relatório para PDF e envio  os bytes do arquivo diretamente para o STREAM de tela. No browser do cliente o Adobe Reader captura isso e abre no browser como arquivo PDF. Não há necessidade de gerar arquivo em disco como eu fazia no início.

Mas como fazer esta exportação! Vou dar duas sugestões. A primeira é aprender como se faz consultando os seguintes links: Link 1 e Link 2. A outra opção é “use o que tá pronto”. Na página de Sistemas c/ Fontes deste blog eu disponibilizo uma aplicação que faz exatamente as coisas que eu descrevi aqui. A aplicação é Contas a Pagar on-line. Nele voce pode encontrar os arquivos .rdlc criados, o DataSet com os DataTables criados e o método de exportação em PDF em funcionamento.  Há métodos para exportão para Excel e PDF, em vetor de bytes ou arquivo. Fica a sua escolha. Inclusive mostra como passar parâmetros para o relatório. Esse parâmetros podem ser exibidos, por exemplo, no cabeçalho do relatório como o nome do estabelecimento ou perído. Uma dica: visite esta dica que lá mostra como exportar diretamente para PDF ou Excel sem ter que passar pelo processo de seleção no ReportViewer.

Adiquira o  projeto e veja uma aplicação prontinha utilizando esses conceitos. Além de estar investindo em seu aprendizado está contribuindo para meus estudos e pesquisas. A implementação completa dos métodos fazem parte da Regisoft Library que voce também pode adquirir.

Bom, é isso. Obrigado pela atenção e até a próxima.

    Servidor de Aplicação em .NET

    A arquitetura em camadas tem sido amplamente adotada pelos analistas e desenvolvedores de sistemas computacionais. Isso porque esta arquitetura favorece a aplicação de vários conceitos envolvendo a engenharia de software como, por exemplo, modularidade, manutenibilidade, etc. O conceito que motivou a escrita deste post é a escalabilidade, ou seja, o desafio de construir sistemas preparados para “crescer”. Um sistema e dito escalável, por exemplo, quando seu desempenho aumenta com acréscimo de hardware. Não estou falando em ficar mais rápido por que agora ele está rodando em um servidor mais rápido do que o antigo. Estou falando em potencial de crescimento e adaptação a cenários de produção. Imagine a situação: Uma pequena empresa com poucos recursos financeiros requisitou da equipe de TI um sistema de gestão empresarial. Após levantamento de requisitos, avaliação das condições de infraestrutura, decidiu-se pela seguinte configuração: arquitetura cliente/servidor. Um servidor de banco de dados foi colocado na rede e a aplicação cliente faria solicitações a este servidor. A aplicação cliente implementava todas as regras de negócio do sistema de gestão e o servidor de banco de dados serviria apenas como repositório de dados. A princípio tudo funcionava bem: LAN com poucos usuários, poucos dados no banco… Mas a empresa cresceu. Mais usuários na rede, maior volume de dados, novas filiais, negócios via internet, novas regras de negócio, etc. Já está claro que o velho sistema precisaria ser reescrito. Talvez até em outra plataforma de desenvolvimento. Sem falar que, possivelmente, novos especialistas em TI precisarão ser contratados ou, pelo menos, os anteriores terão que passar por algum treinamento/reciclagem. Tudo isso porque não se pensou na possibilidade do sistema crescer em necessidades de regras de negócio juntamente com a necessidade de infraestrutura. A pequena empresa, hoje, tem condições para investir em mais computadores-servidores, internet, redes de longa distância. Ela tem alto volume de dados que precisam ser tratados com velocidade dentro e fora do ambiente da empresa. Eu pergunto: é qualquer sistema que pode se adaptar a esta nova realidade? O grande desafio é CONSTRUIR SISTEMAS PREPARADOS PRA CRESCER. O sistema não precisa nascer grande mas deve possuir características que, com pequenas adaptações, tenha seu potencial aumentado.

    Um bom começo para quem prentende trabalhar com escalabilidade é verificar se seu sistema admite a possibilidade de trabalhar utilizando um servidor de aplicação: as aplicações clientes (desktop ou web) fazem requisições a um servidor. Neste servidor estão implementados todas as regras de negócio e esse servidor faz acesso ao banco de dados para, então, responder às solicitações. Para utilizar essa proposta, que modificações voce teria que fazer no seu sistema?

    1. Teria que reescrever o sistema em outra plataforma?
    2. Teria que efetuar algumas mudanças sim. Voce acha que dá pra fazer? Em quanto tempo?
    3. Teria que, primeiro ser treinado em ambiente em camadas pra depois pensar nisso?
    4. Teria que, primeiro mudar sua forma de programar?
    5. Teria que colocar as regras de negócio da aplicação em um só lugar para depois pensar no servidor de aplicação?
    6. Teria que modelar o sistema primeiro em orientação a objetos?
    7. Outro “teria” qualquer….

    Veja que parece simples responder a esta pergunta mas não é tão imediato assim. Nem todos os sistemas são preparados para isso efetivamente. Outras respostas:

    1. Construimos o sistema com esta visão. Foi previsto que o projeto teria grande possibilidade de crescimento tanto em recursos quanto em necessidades.
    2. Sim. É só modificar o arquivo de configurações do sistema para que as aplicações clientes façam solicitações para o servidor.
    3. Sim. Só preciso modificar uma linha do sistema, recompila-lo e recoloca-lo em produção.
    4. Quantos servidores posso utilizar? Pelo menos um servidor para DAO´s e banco de dados e um outro servidor de regra. Poderiam ser mais servidores de aplicação espalhados pela rede. Depende apenas do nível de resposta que a empresa pretende ter e da disponibilidade de recursos físicos.
    5. O sistema permite dividir papéis facilmente.
    6. Outros “só se for agora” qualquer….

    Se voce puder utilizar alguma dessas respostas, parabéns. Voce já está no caminho certo. É essa linha que a engenharia de software moderna quer que os novos sistemas sigam. Para aqueles que aindam não perseguem estes objetivos vou tentar passar algumas dicas como roteiro inicial a seguir.

    Eu utilizava .NET 1.1 quando me fiz a seguinte pergunta: Em J2EE, pode-se configurar a utilização de um servidor de aplicação através dos EJB containers. JBoss é um exemplo de servidor de aplicação gratuito em Java. Qual o servidor de aplicação para .NET??? Há um tempo atrás fui a uma apresentação sobre .NET 2.0 com Visutal Studio 2005. Na saída fiz essa pergunta ao facilitador e ele me respondeu com uma palavra: “Remoting”. Ao chegar em casa me dediquei a pesquisar sobre o assunto. A seguir, deixo indicado um artigo que serviu de base para nossa trajetória sobre o assunto:

    .NET Remoting – Parte 1 – Acessando informações remotamente
    .NET Remoting – Parte 2 – Acessando informações remotamente

    Desde então temos trabalhado para que a construção dos nossos sistemas tenham carateríscas que viabilizem a arquitetura de acesso remoto. As pessoas que acompanharam em nosso blog os post entitulados NHIbernate + Visual Studio: Construindo aplicações em camadas devem ter notado em algumas partes dos códigos e da explanação a presença de flags para utilização de servidor de aplicação. Desenvolvemos uma solução chamada RemoteServer.NET em Visual Studio 2005 com 3 projetos que casa perfeitamente com esses indicadores:

    1. RemoteServerWin: Um servidor de aplicação utilizando .NET Remoting que roda como aplicação do windows.
    2. RemoteServerService: Um servidor de aplicação, também utilizando .NET Remoting que roda como serviço do windows.
    3. RemoteServerSetup: Um instalador dos projetos anteriores.

    Vamos entender o esquema abaixo numa proposta didática, porém bem próxima de uma arquitetura ideal:

    No ínicio do processo temos um usuário utilizando o seu computador para fazer solicitações ao servidor web através de um navegador. O servidor web é responsável apenas pela apresentação e desenho da página web. Qualquer necessidade de processamento de regras de négocio deverá ser enviada ao servidor de negócio. A linha usuario-navegador-servidor web-servidor de negócio poderia ser subistituida por outras configurações: celular-servidor web-servidor de negócio, aplicativo windows-servidor de negócio, etc. O fato é que o servidor de negócio precisa está preparado para receber e responder a requisições remotas. Neste servidor estaria configurado o RemoteServer.NET para responder solicitações da camada de apresentação. Algumas vezes o servidor de aplicação precisaria acessar dados do banco de dados. Esse acesso, de acordo com padrões de projetos e arquitetura em camadas deveria ser através de DAO´s. Logo poderiamos ter um servidor DAO para responder requisições feitas pelo servidor de negócio. Neste servidor DAO também teria instalado o RemoteServer.NET para responder requisições remotas. Por fim, temos uma máquina como servidor de banco de dados para acesso a dados.

    As possibilidades são inúmeras. Imagine um enorme volume de usuários fazendo acesso ao servidor de regra. Poderiamos colocar novos servidores de negócio pra dividir a carga ou mesmo, mais servidores de acesso a dados fazendo com que as requisições fossem aleatórias a estes servidores evitanto o engarrafamento de requisições no mesmo servidor. Poderiamos também fazer replicação sincrona de dados no banco ou mesmo, utilização de cluster para dividir a carga de acesso ao banco de dados. Tudo dependendo do potencial do parque de informática da empresa e necessidade de acesso rápido ás informações. Adicionemos a tudo isso uma dose de XML Web Service para que outra aplicações possam conectar-se diretamente a seu servidor de regras via web.

    As aplicações que voce desenvolve suporta essas possibilidades?  Isso é ESCALABILIDADE.

    Na nossa página de Sistemas c/ Fontes estamos disponbilizando a solução RemoteServer.NET para aqueles que desejarem adquirir e ampliar seus horizontes. Vale lembrar que o RemoteServer.NET sozinho não faz milagre. A aplicação como um todo deve ser pensada para suportar esses requisitos. O primeiro passo é repensar seus conceitos em desenvolvimento e pesquisar soluções que sejam multi-utilizáveis.

    Quem desejar adiquirir esse e outros produtos entre em contato. Teremos o maior prazer em responder. Voce estará contribuindo para manter nossas pesquisas bem como, a qualidade das nossas publicações.

    É isso.

    Visual Studio + NHibernate: Construindo aplicações em camadas – (cont. VI)

    No post anterior criamos as classes que vão dar suporte às regras de negócio da nossa aplicação. Neste post, que é o último desta série, vamos criar a nossa camada de apresentação. Não pretendo aqui esgotar o assunto sobre isso, nem mesmo desenvolver todas as telas do sistema. O que iremos fazer é dá uma idéia inicial sobre a comunicação entre as camadas e criar uma página web que possa servir de base para o trabalho do desenvolvedor.

    Até o momento tudo que fizemos foi puramente conceitual. E, de posse dos conceitos, utilizamos scripts para gerar os códigos. Destaque para algumas bibliotecas que encapsulam funcionalidades ligadas ao Hibernate, visando diminuir codificação e ganho em reaproveitamento de código. Daqui pra frente quem manda é a critatividade e a prática do programador para desenvolver a aplicação de acordo com os requisitos de sistemas definidos no projeto. Eu considero que é deste ponto que se inicia o trabalho de codificação efetivamente, visto que, até o momento, utilizamos geradores de código para criar as camadas que darão suporte a nossa aplicação. Eu utilizo essa prática em todo sistema corporativo que desenvolvo. Claro que a medida que vão surgindo outras necessidades, tanto as bibliotecas, quanto os scripts vão sofrendo adaptações. Por exemplo, desde quando comecei a escrever esta série algumas mudanças foram feitas nos scripts bem como na biblioteca. Isso é fácil de entender: a medida que vamos trabalhando, vamos aprendendo e aprimorando nossos hábitos e conceitos. Isso faz parte do ser humano: fazer hoje, melhor que ontém.

    Então vamos iniciar os trabalhos. Abra a nossa solução no Visual Studio e adicione um novo projeto. Uma vez me perguntaram se este projeto poderia ser em windows forms. Claro que sim. Pode ser qualquer projeto de GUI: web, windows forms ou console. A camada de apresentação é o local onde o usuário final irá interagir com seu sistema. Quem define isso é o documento de requisitos. No nosso caso será um projeto web. Adicione um web site ou um web application. Eu prefiro utilizar web application e com suporte a AJAX. Qual a diferença? Bom… Eu começei no VS 2003 e ele já utilizava o conceito de web application. Eu gostava porque os arquivos .cs não precisavam ser colocados no site em produção. Ele gerava uma única .dll que implementava todas as classes. No web site, temos que colocar em produção os arquivos .cs que serão compilados, gerando as dll’s, em tempo de execução. Vantagem e desvantagem: Na web application qualquer modificação precisa ser recompilada. No web site modificações podem ser feitas diretamente no arquivo em produção. A compilação será feita automaticamente. Por outro lado, na web application tem como evitar a ação de pessoas não autorizadas nos códigos-fontes da  sua aplicação, enquanto no web site não tem como impedir diretamente. Teria que ser via sistama operacional. Enfim, veja o que é melhor. Fiquei com web application… Adicionei projeto web application com nome “AgendaTelefonica”. O Visual Studio gerou os arquivos.

    Primeira coisa a fazer é configurar o Hibernate. Vamos utilizar o web.config para isso. Essa configuração vai dizer ao NHibernate qual banco de dados estamos utilizando e onde ele está (usuario, senha, dialeto, tipo de banco, etc.). Uma outra informação que eu coloco neste arquivo é o nome do assembly O/R. Quem vai ler esta informação é a bilbioteca Regisoft.Camadas.dll para configurar o mapeamento do Hibernate.  Neste arquivo, em nossa aplicação e relacionado ao Hibernate, não mexeremos mais neste arquivo. A menos que desejemos fazer alguma mudança ou adicionar algum recurso novo, como por exemplo, se desejarmos trabalhar como servidor remoto. Mas isso é assunto de outros posts.

    Precisamos adicionar algumas referências em nossa aplicação web. Clique no botão direito do mouse sobre o nome do projeto que acabamos de adicionar e selecione “Add Reference…”. Selecione a guia project e, nessa guia, selecione os projetos BO, Interface e OR (não selecione o DAO) e clique em ‘OK’.. Lembre da obediência a hierarquia em cadamas que discutimos anteriormente. A camada de apresentação só pode fazer requisições à camada de negócio. Nunca à camada DAO. Lembra da biblioteca Regisoft.dll? Adicione ela também. Mas duas bibliotecas serão necessárias: Regisoft.web.dll e Regisoft.Web.UI.WebControls. A primeira possui recursos para manipulação de javascript, limpeza automática de campos da tela, atribuição automática de valores dos objetos O/R a campos da tela, etc. A segunda são alguns componentes da toolbox que eu adicionei alguns novos recursos.  Como voce já sabe, todas essas bibliotecas são encontradas na pasta ‘Bibliotecas‘ no local onde voce instalou o RSClass.

    Para quem tiver alguma dúvida, o arquivo web.config pode ser encontrado no site do tutorial (http://tutorialagendatelefonica.googlecode.com). A Regisoft.Web.UI.WebControls.dll deve ser adicionada também na Toolbox do Visual Studio para facilitar. Para fazer isso clique com botão direito do mouse em qualquer lugar da Toolbox e selecione “Add Tab“. Dê um nome: “Regisoft”. Clique ainda com botão direito dentro da tab criada e selecione “Choose Items…“. Quando a janela aparecer clique em “Browse” e localize a biblioteca Regisoft.Web.UI.WebControls.dll (na pasta ‘Bibliotecas’ no local de instalação do RSClas. Confirme… Pronto! Os componentes foram adicionados. Abra a página Default.aspx e veja que na tab “Regisoft” possui alguns componentes. Inclusive essa é a maneira de adicionar webcontrols na Toolbox. Toda vez que voce baixar um componente visual pode adicioná-lo na toolbox dessa forma – Dica.NET ;)

    Mas algumas considerações na configuração do NHibernate. No web.config há informações sobre o banco de dados (driver, dialect, conecctionstring, etc.). Como estamos utilizando o Firebird precisamos adicionar o driver do banco ao sistema. Clique no projeto web com botão direito do mouse e selecione ‘Add Reference…‘. Localize o arquivo FirebirdSql.Data.FirebirdClient.dll que está na pasta ‘Bibliotecas’ no local de instalação do RSClass e adicione ao projeto. Outro arquivo que também terá que adicionar ao projeto web é o NHibernate.ByteCode.Castle.dll. Nessa nova versão do NHibernate ele precisa desse arquivo. Ainda não li sobre a utilidade. Mas devemos adicionar se não o NHibernate não irá funcionar. Quem souber da utilidade deste arquivo e quiser contribuir eu agradeço.

    Se tudo foi feito corretamente teremos a seguinte tela (mais ou menos assim):

    Já estamos com nosso ambiente preparado para iniciar os trabalhos. Vamos criar nossa primeira página web. Faremos uma página para inclusão de UF. Há quem ache que não precisa. Basta popular o banco de dados com essas informações, já que as UF não mudam constantemente. Eu concordo. Mas vamos construir para fins didáticos. Pra não perder a prática utilizaremos o RSClass pra facilitar o trabalho. Não iremos nos preocupar com aparência da página fica como exercício para os interessados.

    Como não é uma tabela com muitos dados vamos gerar como tabela simples. No RSClass acesse o menu Webform->Tabela. Configure como mostrado abaixo.

    gerar_webformtabela

    Algumas informações importantes sobre essa geração de páginas:

    1. Na pasta destino voce pode selecionar o local do deu projeto onde quer que seja gerado os arquivos. Pode ser na principal ou em subpastas do seu projeto;
    2. Atenção para isso: o título da página deve ser informado sem acentuação e cedilhas. Os acentos só devem ser colocados quando a página for incluída no projeto e convertida em web application. Veremos isso mais tarde;
    3. No campo arquivo é o nome do arquivo a ser gerado. Não coloque extensão. O próprio RSClass irá fazer isso.
    4. A namespace é formada pelo nome do projeto (no nosso caso AgendaTelefonica) e pelas pastas internas onde o arquivo será gerado separado por ponto(.). Exemplo se voce gerar dentro de um projeto Estoque na pasta interna Almoxarifado a namespace deve ser Estoque.Almoxarifado;
    5. Selecione a tabela;
    6. Se voce pretende usar uma master page na página geraada marque a última caixa. A página será gerada com estrutura de WebForm Content. No nosso exemplo não estamos utilizando.

    No Visual Studio, clique em “Show All Files“, selecione os dois arquivos gerados, clique em um deles com o botão direito do mouse e selecione “Include In Project“. Agora, clique em UnidadesFederacao.aspx com o botão direito do mouse e selecione “Convert to Web Application“.

    Vamos gerar agora a classe de acesso aos BO´s. Como já dissemos anteriormente vamos utilizar uma arquitetura em camadas sendo que os acessos aos componentes da camada inferior serão feitos por uma única via. Abra o RSClass e no menu Gerar->BOAccess.cs gere o arquivo.  Usando o mesmo procedimento do parágrafo acima inclua o arquivo no projeto (Include in Project).

    Defina a página UnidadesFederacao.aspx como “Set As Start Page” e execute a aplicação. Vamos ver se funciona…

    Pra variar, PROBLEMAS!!!!! Vamos as correções:

    1. Normalmente eu crio sistema com controle de acessos. E este, como foi definido nos requisitos inicias, também deve ter. Deveriamos ter feito primeiro o controle de acesso ao sistema num tela de login. Mas como o objetivo é didático pulamos esta etapa. Então vamos comentar algumas lihas da nossa primeira página. No método protected void Page_Load(object sender, EventArgs e) da página comente as linhas if (u == null) e
      Response.Redirect(“~/Index.aspx”); Voce sabe. Comentar é adicionar duas barras (//) na frente da linha.
    2. Eu também constumo desenvolver sistemas que eu chamo multi-empresa. São sistemas que podem ser utilizados por várias empresa ao mesmo tempo. Uma sem acessar os dados da outra. Nesse caso no cadastro do usuário é definido a que empresa ele pertence. Assim no momento das listagens e outra operações é informado ao sistema a empresa do usuário e as operações só serão executadas em dados dessa empresa. Esse não é o nosso caso. Então localize no sistema a o método protected DataTable getDataTable(). Altere a linha IList<AgendaTelefonica.OR.Uf> lst = BOAccess.getBOFactory().UfBO().Listar(u.IdEmpresa) para IList<AgendaTelefonica.OR.Uf> lst = BOAccess.getBOFactory().UfBO().Listar(“Sigla”). Veja que a única coisa que mudou foi o parâmetro do método ‘Listar‘ que era ‘u.IdEmpresa‘ e passou a ser ‘Sigla‘.

    Depois dessas modificações a página já pode ser testada. Note e a página é bem simples e complatemente funcional. Seria interessante adicionar alguns recursos visuais com CSS ou coisas do tipo. Mas não é objetivo deste material.

    A verdade é que os geradores de código não resolvem todos os problemas. Mas adiantam bastantes. Com algumas modificações podemos ter ótimos resultados. Imagine se tívessemos que escrever tudo do zero…

    Vamos agora ilustrar a adição de métodos de acesso a dados no DAO. Abra o UfDAO.cs e adicione as seguintes linhas:

    public Uf SelecionarPorSigla(string sigla)
    {
    return this.SelecionarPor(“Sigla”, sigla);
    }
    public IList<Uf> ListarPorDescricao(string descricao)
    {
    string hql = @”select uf from Uf uf
    where uf.Descricao like :descricao
    order by uf.Descricao”;
    IQuery query = Get<ISession>().CreateQuery(hql);
    query.SetAnsiString(“descricao”, descricao + “%”);
    return query.List<Uf>();
    }
    public IList<Uf> ListarPorSigla(string sigla)
    {
    ICriteria crit = Get<ICriteria>()
    .Add(Expression.InsensitiveLike(“Sigla”, sigla, MatchMode.Start))
    .AddOrder(Order.Asc(“Descricao”));
    return crit.List<Uf>();
    }

    Veja que criamos 03 métodos DAO´s. Um com critéria, outro com HQL (Hibernate Query Language) e outro utilizando um método nativo da classe BaseDAO. Veja que o controle da sessão do Hibernate vem do Get<ISession>() e o critéria vem do Get<ICriteria>(). Ambos implementados no BaseDAO. Veja também que com a utilização da nossa bilbioteca a construção de métodos de acesso a dados com Hibernate é bem facilitada. Abra tambem a interface IUfDAO.cs e adicione as seguintes linhas:

    Uf SelecionarPorSigla(string sigla);
    IList<Uf> ListarPorDescricao(string descricao);
    IList<Uf> ListarPorSigla(string sigla);

    Qualquer novo método que for adicionado nos DAO´s deverá também adicionar a declaração na interface correspondente. Agora abra o UfBO.cs e adicione as seguintes linhas:

    public Uf SelecionarPorSigla(string sigla)
    {
    if (sigla == string.Empty || sigla == null)
    throw new ExceptionRS(“Necessário informa a sigla”);
    return ufDAO.SelecionarPorSigla(sigla);
    }
    public IList<Uf> ListarPorDescricao(string descricao)
    {
    if (descricao == string.Empty || descricao == null)
    throw new ExceptionRS(“Necessário informa a descricao”);
    return ufDAO.ListarPorDescricao(descricao);
    }

    Na regra de negócio nos fazemos chamadas aos nóvos métodos do DAO. Adicionamos uma pequena regra que determina que os parêmetros de entrada não podem ser vazio ou nulos. Todas essas validações podem ser colocadas aqui. Eu diria que DEVEM. Mas há quem coloquem apenas na página web através dos componentes ASP.NET de validações. Eu costumo validar os dados de entrada tanto na tela com os componentes de validação, quanto no objeto de négocio. Isso por que caso eu esqueça de validar na tela de entrada certamente no objeto de negócio uma excessão será gerada.

    Como fizemos no IUfDAO.cs, vamos fazer com IUfBO.cs. Abra-o e adicione as seguintes linhas:

    Uf SelecionarPorSigla(string sigla);
    IList<Uf> ListarPorDescricao(string descricao);
    IList<Uf> ListarPorSigla(string sigla);

    Note que algumas linhas já estão lá definidas assim como no UfBO.cs e IUfBO.cs. Essas linhas foram adicionadas pelo RSClass.

    Se desejarmos utilizar esses novos métodos na camada de apresentação precisamos primeiro declará-los na camada de negócio. Isso para obedecer a hirerarquia entre as camadas. Vamos faze isso. Abra o UfBO.cs e adicione os seguintes métodos:

    public Uf SelecionarPorSigla(string sigla)
    {
    return ufDAO.SelecionarPorSigla(sigla);
    }
    public IList<Uf> ListarPorDescricao(string descricao)
    {
    return ufDAO.ListarPorDescricao(descricao);
    }
    public IList<Uf> ListarPorSigla(string sigla)
    {
    return ufDAO.ListarPorSigla(sigla);
    }

    Também será necessário acrescentar algumas linhas na interface IUfBO.cs:

    Uf SelecionarPorSigla(string sigla);
    IList<Uf> ListarPorDescricao(string descricao);
    IList<Uf> ListarPorSigla(string sigla);

    Lá já tem várias métodos declarados. São os métodos que podem ser chamados na camada de apresentação. Agora nós adicionamos mais 03 métodos para serem utilizados. Após estes procedimentos, os novos métodos já estão disponíveis para utilização na página. Fica como exercício: modificar a página para localizar dados por descrição. Dica: O RSClass possui outros layouts de página para serem gerados. Cada layout tem uma finalidade bem definida. Para mais informações acesse http://rsclass.wordpress.com.

    É possível modificar os arguivos gerados para que os DAO´s, BO´s e banco de dados possam rodar em um servidor de aplicação, enquanto que o servidor web e/ou outros programas desktop rodam em outras máquinas fazendo solicitações ao servidor. Mas isso é assunto de posts futuro.

    Deixo como exercício para o leitor implementar as outras páginas e recursos do site de acordo com a especificação inicial. Também me coloco a disposição para tirar dúvidas, dar treinamento, sugestões,  etc. Veja a página de Contato e sabia como me localizar. Acesse http://tutorialagendatelefonica.googlecode.com para baixar o código-fonte completo deste tutorial.

    CONCLUSÃO

    Desenvolver sistema é um trabalho desgastante. Mas este desgaste pode ser bem diminuido. Padrões de projetos, geradores de código, pesquisas e toda a engenharia de software podem ser aliados nessa tarefa de desenvolver bons programas.

    Aproveito para indicar nossa área de Sistemas c/ Fontes. Adiquira um projeto completo para auxiliar no seu estudo e contribuir em nossas pesquisas.

    Desde já agradeço a todos e até os próximos.

    Visual Studio + NHibernate: Construindo aplicações em camadas – (cont. V)

    No post anterior desta série discutimos sobre a criação da camada DAO. Geramos as classes e interfaces, além de preparar um DAOFactory que é o caminho por onde serão feitos acessos às funcionalidades dos DAO´s. Vimos também como utilizar uma classe abstrata BaseDAO que, combinada com o MyGeneration, pode facilitar bastante no uso dos recursos do Hibernate.

    Neste post vamos discutir sobre a camada de regras de negócio (BO). Vamos acessar os DAO´s através de um DAOAccess e criar um BOFactory para que a camada de apresentação possa utilizar este caminho para fazer acessos ou requisições às regras de negócio.

    Como o próprio nome já diz a camada de regras de negócio define as regras ou comportamentos que a aplicação terá durante o processamento de requisições oriundas da camada de apresentação. Esta camada pode ser formada por uma ou várias classes que serão responsáveis por controlar a entrada e saída de informações. Não acho legal criar uma única classe para controlar todas as regras de negócio da aplicação. Procuro agrupar em classes, separando as operações relacionadas. Dessa forma consigo ter melhor visão dos módulos da aplicação.

    Mas o que tem numa classe de negócio?! Como sabemos uma classe é formada basicamente por métodos e propriedades. Os métodos irão ser chamados na camada de apresentação para realizar as operações de negócio. As porpriedades irão formar parâmetros de entrada ou saída da classe para determinar algum comportamento do método. Vamos conhecer algumas métodos e propriedades que podemos colocar numa classe de negócio:

    1. Inclusão e alteração de dados. Esses métodos são os mais comuns em qualquer aplicação que utilize banco de dados. Eles serão chamados pela camada de apresentação para realizar a devida operação no banco de dados (através dos DAO´s); Nesses métodos podemos encontrar procedimentos comuns em operações de inclusões e alterações. E, por exemplo:
      • validação de permissões de usuário;
      • validação de campos;
      • verificações de relacionamentos entre tabelas do banco;
      • verificações de violação de índices ou chaves;
      • abertura e fechamento de transações;
      • inserções e/ou alterações em tabelas;
      • outros processos durante a operação.
    2. Exclusões. Esses métodos realizam operações de exclusão de dados do banco. Internamente também possui procedimentos comuns ao processo:
      • validação de permissões;
      • verificação de violação de relacionamentos;
      • verificações de violação de índices ou chaves;
      • abertura e fechamento de transações;
      • eliminações de dados em tabelas
      • outros processos durante a operação.
    3. Seleções de linhas da tabela. Esses métodos vão dar suporte a consultas e listagens que a camada de apresentação possa necessitar e também para outros objetos de negócio:
      • Seleção de uma linha da tabela por chave primária ou índice único;
      • Listagem de registros das tabelas controlada ou não por filtro;

    Acredito que, no mínimo, todas as aplicações realizam alguma ou todas as operações e sub-processos citados acima. Já que esses processos são comuns a maioria das aplicações em camadas e que fazem acesso a banco de dados, seria interessante que pudessemos automatizar a criação desses métodos. Foi exatamente o que eu fiz criando o RSClass. Vamos utilizá-lo para gerar as classes da nossa camada de negócio.

    Claro que, obedecendo a hierarquia em camadas, as classes de negócio fazem chamadas às classes DAO´s. E essas chamadas são feitas atravéz do DAOFactory por um DAOAccess. Parece complicado mas não é. Apenas estou determinando que nenhuma classe DAO seja instanciada com new diretamente na camada de negócio. Quem terá essa responsabilidade será o DAOAccess e quem irá responder a essas solicitações de instanciamento dos objetos é o DAOFactory.

    O processo de criação dos BO´s e das interfaces usando o RSClass é similar ao que fizemos na criação dos DAO´s e suas interfaces. Inclusive sei que alguns leitores já se adiantaram e geraram essas classes por conta própria, através de nossa explicação anterior. ;) Só irei fazer alguns comentários sobre este processo:

    1. As intefaces devem ser geradas na pasta BO da biblioteca AgendaTelefonica.Interface. O RSClass já sabe disso e gera os arquivos no local correto de acordo com as configurações realizadas anteriormente.
    2. De maneira similar, os BO´s serão gerados na pasta da biblioteca AgendaTelefonica.BO.
    3. No Visual Studio, após ter sido gerado os arquivos, selecione as classes e, clicando com o botão direito do mouse em algum dos arquivos selecionados, selecione a opção “Include In Project“. Isso deve ser feito em cada biblioteca onde os arquivos foram gerados.
    4. Tembém será necessário “Add Reference…” no projeto AgendaTelefonica.BO para os arquivos Regisoft.dll e Regisoft.Camadas.Interface.dll. Normal. Afinal de contas toda essa estrutura utiliza a Regisoft Library pra agilizar o processo. Esses arquivos podem ser encontrados na pasta ‘Bibliotecas‘ no local onde voce instalou o RSClass. Se voce quiser adiquirir os fontes para estudar, guardar, aprimorar… acesse a página “Sistema c/ Fontes” e saiba como.
    5. Após a realização dos procedimentos o Solution Explorer estará assim:

    É importante conhecer o conteúdo dos arquivos gerados e entender seu funcionamento. Destaque para os arquivos

    • DAOAccess.cs, que se comunica com a camada DAO através do DAOFactory.cs;
    • BOFactory.cs que será a via de comunicação entre a camada de apresentação e a regra de negócio.
    • IBOFactory.cs que é a interface de exposição do BOFactory.cs

    Aproveite e olhe a estrutura dos arquivos BO´s gerados, por exemplo CidadeBO.cs. Veja que nele e em todos os outros BO´s existe uma estrutura inicial com aquelas funcionalidades principais e comuns a todos os arquivos de regra de negócio (valiação, inserção, exclusão, etc.).  Note também que no construtor do BO existe a ligação com o DAO correspondente e todos os métodos fazem uso desta instãncia do DAO.

    Não é necessário ter um BO para cada DAO correspondente. Voce pode agrupá-los em funcionalidades próximas na sua aplicação, criando assim uma visão de módulo. Por exemplo, voce pode embutir num único BO as funcionalidades para controlar endereços. Neste BO irá conter todos os métodos para gerenciar endereços: UF, Cidade, CEP, etc.  Assim, na camada de apresentação, voce pode fazer uso de um certo EnderecoBO e nele já possuir tudo que se precisa pra controle de endereço: seleções, inclusões, alterações, etc. de Uf’s, cidades, ceps, etc’s. Inclusive está é a atitude mais comum no que diz respeito a criação de BO’s.

    Certamente durante o desenvolvimento da camada de apresentação será necessário criar vários novos métodos para operações de seleção de dados e/ou persistência, tanto nos DAO’s quanto nos BO’s. Paralelamente, alterações nas respectivas interfaces também serão necessárias. Tudo para que os BO’s realizem com exatidão seu papel de controlar a regra do negócio. Montamos o esqueleto principal que dará suporte a aplicação. No próximo e último post estaremos criando o projeto do site para camada de apresentação. Vamos criar uma tela que servirá de base para entendimento do processo e criação das outras. Vamos criar também novos métodos em alguns DAO´s e BO´s para mostrar um pouco do potencial do Hibernate nesta questão.

    Os arquivos gerados até o momento podem ser baixados no site http://tutorialagendatelefonica.googlecode.com.

    Fiquem a vontade para comentar. Espero que estejam gostando e até o próximo!

    Visual Studio + NHibernate: Construindo aplicações em camadas – (cont. IV)

    No post anterior criamos as classes e os mapeamento O/R do Hibernate. Vimos que essas classes farão o papel de transferir dados entre as camadas. Neste post vamos construir os DAO´s. Vamos definir os componentes que farão acesso ao banco de dados, ou seja, os DAO´s.

    Vamos falar um pouco sobre alguns detalhes importantes neste processo. No post anterior indicamos um material sobre conhecimentos preliminares em relação ao Hibernate. Importante ter lido antes de continuar.

    Nunca tive muita afinidade com a arquitetura cliente/servdor. Aquela onde existe um servidor de banco instalado em algum lugar da rede e as aplicações acessam diretamente este servidor fazendo requisições e persistindo dados. Esse processo é muito comum em Delphi e Visual Basic. Os programadores constroem um executável, embuntindo as regras de negócio e os comandos SQL no programa. Sempre achei isso meio complicado de gerenciar. E, de certa forma, é mesmo. Controle de transação, travamento de linhas, várias máquinas com o mesmo executável instalado e acessando o mesmo banco, etc. passam a ser preocupações do desenvolvedor que deve embutir soluções no programa. Mesmo usando o Delphi eu preferia separar alguns papéis. Eu fazia assim: a aplicação era responsável apenas por solicitar e exibir dados so servidor. As procedures do banco eram responsáveis para incluir, alterar e excluir dados (regras de negócio e DAO). Nenhuma aplicação poderia efetuar inserções, alterações ou deleções diretamente nas tabelas. Essas operações tinham que passar pelas procedures. As aplicações parametrizava dados e passava para a procedure. A aplicação permanecia aguardando o final da execução da procedure para saber se houve algum problema ou tudo foi realizado com sucesso. Nas procedures eram definidas regras da aplicação: validações, integridades, restrições, procedures paralelas (nada de triggers), etc. Inclusive acho isso muito bom. Não existe nada mais rápido pra banco de dados do que procedures. Eu disse NADA!!!!!!!!

    Como nada é perfeito, tem um problema: se mudar a aplicação para outro banco as procedures teriam que ser reescritas!!!! Eu tinha uma aplicação mediana em SQL Server com mais de 200 procedures que teria que migrar para Oracle. Sem chances reescrever as procedures novamente. E se tivesse que mudar pra outro banco? Reescrever tudo outra vez?.

    Neste cenário entrou o Hibernate! Com ele foi possível ganhar indepêndencia de banco de dados. Mas nem tudo são flores. As procedures do banco geram pouco tráfego de rede. O Hibernate gera auto nível de tráfego. Por isso é importante ter cuidado ao utiliza-lo. Sem falar em outras situações: gerenciamento de sessão, conectividade com outros bancos, HQL (o SQL do Hiberante), configurações, etc. Por tudo isso é importante planejar bem o seu uso. Dediquei um pouco do meu tempo a pesquisar e planejar. Construí uma biblioteca que gerencia inúmeras situações que acabam sendo repetitivas nas aplicaçãoes com Hibernate. Eu a chamei de Regisoft.Camadas. Ela faz parte de um pacote (Regisoft Library.NET) com outras bilbiotecas que utilizo no processo de desenvolvimento. Veja as classes que a biblioteca Regisoft.Camadas possui:

    1. NHibernateHelper – (Regisoft.Camadas.NHibernateHelper) Responsável por configurar e gerenciar o Hibernate dentro da aplicação. Inicialização das classes de mapeamento, gerenciamento da sessão, conectividade com um ou vários bancos de dados ao mesmo tempo são responsabilidades desta classe. Não precisa ser instanciada nem utilizada diretamente. Uma outra classe chamada BaseDAO fará uso desta classe internamente.
    2. BaseDAO – Todos os DAO´s devem herdar dessa classe abstrata. É um DAO genérico que é responsável por dar suporte, através de seus métodos e propriedades, ás operações envolvendo persistência: inserções, alterações, exclusões, transações, seleção de dados, validação de campos not-null, controle de objetos persistentes e transientes, verificação de integridade antes de uma exclusão e outras mais. Existe uma versão bem completa usando o Generic da versão .NET 3.5 (Regisoft.Camdas.Generic.BaseDAO<T,ID> ) e uma versão descontinuada sem Generic (Regisoft.Camadas.BaseDAO). A versão sem Genéric existe por compatibilidade retroativa. Aplicações desenvolvidas em .NET 1.1 ou anterior utilizam esta versão (não valia a pena mudar).

    Eu utilizo esta biblioteca em TODAS as aplicações que desenvolvo. Ela me permite abstrair da problemática do Hibernate. Não será diferente na nossa aplicação de Agenda Telefônica On-Line. Vamos gerar nossos DAO´s herdando da classe abstrata dessa biblioteca. Quem desejar escrever seu próprio BaseDAO ou sua própria biblioteca fique a vontade. Tem um post aqui que fala sobre as funcionalidades básicas que todo DAO genérico tem que ter. Leia mais… Uma novidade: o nosso BaseDAO também pode ser configurado para trabalhar numa arquitetura que faz uso de um ou mais servidores de aplicações. Clique aqui e saiba mais sobre essa possibilidade.

    Esses arquivos podem ser encontrados na pasta ‘Bibliotecas‘ no local onde foi instalado o RSClass – Gerador de Classes.

    Utilizando a biblioteca assima não precisaremos escrever manualmente um DAO para cada tabela do banco. Podemos utilizar o RSClass para gerar os arquivos necessários. E vamos fazer isso agora. Na página inicial do post disponibilizei informações sobre onde baixar o RSClass. No post anterior fizemos a configuração do projeto e geramos os arquivos de mapeamento (.cs e .hbm.xml). Neste post vamos repetir o processo utilizando outra opção Gerar -> .DAO para gerar os arquivos de acesso a dados do sistema. Não será necessário refazer as configurações já que o RSClass guarda essas informações.

    Gerando as interfaces e os DAO´s

    Abra o RSClass e acesse a opção Gerar -> .DAO, marque a opção “Todas“; deixe as outras como estão. No nosso caso ficou assim:

    rsclass_gerar_dao

    Clique em ‘Gerar‘. Uma confirmação de localização será solicitada. Confirme e aguarde. Ao final voce receberá uma mensagem de sucesso da operação.

    Vamos repetir o processo para gerar as interfaces. Acesse a opção no menu Gerar->.Interface->.DAO. Marque a opção ‘Todas’ e clique em gerar. Confirme a localização e aguarde a informação de operação realizada com sucesso.

    Ufa! Os arquivos foram gerados. Agora vamos ao Visual Studio.

    No Visual Studio

    Com os arquivos gerados nas suas respectivas pastas precisamos agora inclui-los em seus projetos. O Visual Studio precisa reconhece-los como parte do projeto. Os passos a seguir devem ser efetuados em cada projeto do Visual Studio, no local onde os arquivos foram gerados.

    1. Selecione o projeto. Se os arquivos gerados não tiverem aparecendo clique no botão “Show all Files“. Depois selecione os arquivos, clique em qualquer dos arquivos com o botão direito do mouse e selecione a opção “Include In Project“.

    Chegou a hora de utilizar a nossa biblioteca. Voce terá que adicionar as bibliotecas que voce baixou aos projetos.

    1. Projeto AgendaTelefonica.DAO: Clicando com o botão direito do mouse sobre o projeto selecione “Add Reference…“. Selecione a aba Browse e localize os arquivos Regisoft.Camadas.dll, Regisoft.dll e Regisoft.Camadas.Interface.dll na pasta ‘Bibliotecas’ no local o RSClass foi instalado. Selecione-as e clique em Ok.
    2. Proejto AgendaTelefonica.Interface: Clicando com o botão direito do mouse sobre o projeto selecione “Add Reference…“. Selecione a aba Browse e localize as bibliotecas Regisoft.dll e Regisoft.Camadas.Interface.dll (não inclua neste projeto Regisoft.Camadas.dll) no mesmo local do item anterior. Selecione-as e clique em Ok.

    Se tudo foi feito como indicado o Solution Explorer estará como abaixo quando apresentar os projetos AgendaTelefonica.DAO e AgendaTelefonica.Interface.

    Tecle Ctrl+F5 para montar o projeto. Se nenhum erro ocorrer voce concluio com sucesso essa etapa. No máximo, voce receberá uma mensagem informando que não há nenhum projeto que possa ser executado.

    Vamos agora analisar os arquivos gerados.

    1. Abra primeiro o arquivo CidadeDAO.cs. Veja que não existe nada de extraordinário nele. Apenas 03 construtores diferentes na classe e um método que sugere a listagem de cidades pela UF. O mais importante é a definição da classe que herda de uma BaseDAO<Cidade,long> e uma interface ICidadeDAO. A BaseDAO é a classe que implementa as funcionalidades de persistências que já estão prontas para serem usadas. Como é uma classe genérica estamos usando <Cidade,long> que diz que o DTO a que esta classe se refere é ‘CIDADE’ e diz também que possui um campo chave primária do tipo ‘long’. É provável que precisemos de algumas novas funcionalidades na classe CidadeDAO.cs mas iremos adiciona-la depois. O principal (inclusão, exclusão, alteração, seleções de dados, transações, ect.) já está disponível pela herança. Abra também a classe ICidadeDAO.cs e veja que lá também não existe nada de mais. Apenas as herança de outra interface genérica e a assinatura de um método presente na classe CidadeDAO.
    2. Abra agora o arquivo DAOFactory.cs. Este será o arquivo por onde as regras de negócio farão acesso aos DAO´s. Voce entenderá isso melhor quando trabalharmos na geração dos BO´s. Veja que também possui uma inteface na sua declaração. Veja que seu construtor possui maneiras para acessar os DAO´s: com ou se servidor remoto. É possível planejar este sistema paraexecutar DAO´s e banco de dados numa máquina, regras de negócio em outra e servidor web em outra. Mas isso não faz parte do escopo do nosso projeto. Quem desejar conhecer mais sobre este assunto aguarde post posteriores ou registre algum comentário. Por hora voce deve entender que os DAO´s permitem flexibilidade de acesso graças a sua estrutura e o factory dos DAO´s sabe disso, permitindo que o programador escolha a forma de acesso que deseja trabalhar. Mas abaixo no arquivo voce vê exatamente os construtores dos DAO´s sendo chamados de acordo com aqueles construtores que mostramos no item 1, na classe CidadeDAO.cs que usamos como exemplo. O mais importante na nossa arquitetura é saber que os chamados aos DAO´s serão feitos através deste Factory (um padrão de projeto).

    Estude bem este processo e os arquivos gerados. No próximo post vamos gerar os BO´s com suas interfaces. O procedimento é similar ao utilizado na geração dos DAO´s e suas interfaces. Estamos abertos a dúvidas e sugestões.

    Se voce gostou e deseja ter os fontes dessas bibliotecas clique aqui. Conheça uma forma de adquirir ajundando a manter nossas pesquisas.

    Outra coisa: Acesse http://tutorialagendatelefonica.googlecode.com para baixar o projeto gerado nessa etapa.

    Até o próximo.

    Visual Studio + NHibernate: Construindo aplicações em camadas – (cont. III)

    No post anterior criamos o ambiente da aplicação no Visual Studio. Criamos os sub-projetos e definimos as hierarquias de acesso que caracteriza o desenvolvimento em camadas.

    Neste post iniciaremos a codificação do nosso projeto Agenda Telefônica On-Line. O primeiro projeto que iremos codificar é o AgendaTelefonica.OR. Este projeto (ou esta biblioteca) será formado pelas classes que farão o papel de transferência de dados (DTO) entre as camadas. Essas classes ou os objetos irão trafegar livremente entre as camadas levando e trazendo informações. Já discutimos isso no post anterior. Neste projeto também dever haver os arquivos de mapeamento do Hibernate. As classe que vamos criar são as nossas ferramentas de trabalho. Os arquivos de mapeamento são as ferramenta de trabalho de Hibernate. Para cada classe criada deve existir um arquivo .hbm.xml correspondente. Este arquivo possui regras para mapeamento da classe com o banco de dados (not-null, FK, PK, FK, tipos e tamanho dos campos, etc.). Na prática, os arquivos .hbm.xml representam exatamente os campos das tabelas do banco de dados com seus respectivos tipos e relacionamentos. As classes também são uma retratação deste mapeamento.

    Para cada tabela do banco deve existir:

    1. Um arquivo .hbm.xml que corresponde ao mapeamento relacional do Hibernate com a tabela do banco;
    2. Um arquivo .cs (poderia ser em outra linguagem) da classe que também corresponde a tabela do banco de dados.

    Por isso que eu chamo (eu e todo mundo que usa Hibernate) esse projeto de AgendaTelefonica.OR. O OR significa Objeto/Relacional. Como ainda não existe uma banco popularmente conhecido orientado a objeto, o Hibernate faz esse relacionamento pra nós. Ele transforma o paradigma relacional do banco de dados em orientado a objeto pra faciliar o desenvolvimento das aplicações. Tudo que nós faremos durante o desenvolvimento em orientação a objeto, será transformado pelo Hibernate em paradigma relacional (SQL) que é o que o banco efetivamente entende.

    Então vamos criar os dois arquivos para cada tabela da nossa aplicação e inserí-lo no Visual Studio. Como escrever esses arquivos é uma tarefa repetitiva e metódica, é interessante que se trabalhe com gerador de código. Vamos utilizar o RSClass para gerar os arquivos. Este programa foi indicado para instalação no primeiro post deste tutorial.

    A utilização do RSClass é bem simples. Ao executar o programa pela primeira vez deve-se configurar o ambiente. Acesse o menu Arquivo->Configuração e efetue as modificações necessárias. No meu caso ficou assim:

    rsclass_config

    A pasta destino deve ser a pasta da solução criada pelo Visual Studio no post anterior. Note também que o no campo projeto o nome foi informado compatível com as camadas geradas no post anterior.

    Feita as configurações, ainda no RSClass acesse o menu Gerar -> .OR, marque a opção Todas e clique no botão Gerar. Na caixa de diálogo confirme o destino informado pelo sistema e aguarde a informação de que tudo foi gerado com sucesso. Se o destino não tiver correto cancele a operação e reconfigure tudo na tela de configuração do programa.

    Se tudo foi gerado corretamente, quando abrir no Visual Studio a nossa solução, vai encontrar algo assim (selecione o projeto AgendaTelefonica.OR, localize no Solution Explorer o botão “Show All Files” e clique nele):

    Finalmente temos mais duas configurações a fazer:

    1. Incluir ou anexar ao projeto AgendaTelefonica.OR os oito arquivos gerados;
    2. Alterar as propriedades “Buid Action” dos arquivos .hbm.xml.

    Vamos fazer isso. Selecione os oito arquivos e, com eles selecionados, clique em algum com o botão direito do mouse e clique na opção “Include in project“. Depois selecione apenas os arquivos com .hbm.xml e, com eles selecionados, clique em algum deles com o botão direito do mouse e clique na opção “Properties”. Quando a aba de propriedades aparecer, mude o “Build Action” para “Embedded Resource“.
    Essa mudança fará com que os arquivos do hibernate seja embutidos na bliblioteca da classe durante a compilação. É comum esquecer de realizar este processo. Na execução da aplicação, o Hibernate vai gerar uma exceção (um erro) que muitas vezes não é tão fácil de identifcar que o problema é não ter alterado a propriedade Build Action dos .hbm.xml. Por isso FIQUE ATENTO A ESTE PASSO. Se tudo foi feito corretamente o Solution Explorer estará assim:

    E a propriedade Build Action de todos os .hbm.xml estarão assim:

    Mais uma coisa: vamos adicionar uma outra biblioteca ao projeto AgendaTelefonica.OR. Clique com botão direito do mouse sobre o projeto e selecione “Add Reference…”. Localize o arquivo Regisoft.dll que está em ‘Bibliotecas‘ na pasta de instalação do RSClass e adicione ao projeto.

    Pronto. Vencemos mais esta etapa. Já temos nossa blibioteca com as classes e mapeamento para Hibernate. Inclusive as classes dessa biblioteca irão servir como objetos de transferência de dados (DTO). Tente compilar/executar a solução. Não deve dar nenhum erro,  no máximo um um aviso informando que não há nenhum projeto que possa ser executado. Normal… Afinal são apenas Class Library.

    Também é interessante que voce abra os arquivos .cs e os arquivos .hbm.xml gerados e tente identificar os componentes comparando com as tabelas do banco de dados. Se voce desejar se aprofundar neste conhecimento, abaixo, tem um link para uma excelente apostila sobre o entendimento do Hibernate e suas configurações nos arquivos de mapeamento. Vale apena olhar. Fala sobre o Hibernate do Java, mas a compreensão é a mesma para o NHibernate do .NET.

    Clique aqui e veja a apostila.

    No próximo post vamos trabalhar com o projeto AgendaTelefonica.DAO e AgendaTelefonica.Interface, na pasta DAO. Vamos criar os DAO´s e as interfaces para os mesmos.

    Até lá.

    Visual Studio + NHibernate: Construindo aplicações em camadas – (cont. II)

    No post, anterior foram definidos o ambiente de trabalho e requisitos do Sistema Agenda Telefônica on-line. Agora vamos definir o ambiente de desenvolvimento da aplicação no Visual Studio. Lembre-se que será definido em camadas. É comum definir um único Project no Visual Studio e criar pastas dentro deste projeto para definir os DAO´s, BO´s e DTO´s, etc. Faremos um pouco diferente. Vamos criar uma Solution e, nela, adicionaremos projetos que irão acomodar os objetos das camadas.

    Criar a solução…

    Agora vamos adicionar projetos a nossa solução. Vamos adicionar inicialmente 4 projetos:

    1. AgendaTelefonica.OR – Para acomodar os objetos de transferência de dados (DTO´s). Neste projeto iremos adicionar as classe e os arquivos de mapeamento do NHibernate com o banco de dados;
    2. AgendaTelefonica.Interface – Para acomodar as classes de interface dos DAO´s e dos BO´s. Internamente haverá duas pastas, DAO e BO, que acomodará as interfaces respectivas.
    3. AgenteTelefonica.DAO – Para acomodar os DAO´s;
    4. AgendaTelefonica.BO – Para acomodar os objetos de negócio.

    Falta ainda adicionar um último projeto qué é exatamente a aplicação web; o site por onde o usuário irá acessar o nosso sistema. Mas vamos deixar isso para o final.

    Adicionando os projetos…

    Após ter criado este projeto, crie duas pastas: DAO e BO. Até o momento o Solution Explorer deve estar assim:

    Ao final da criação dos projetos o Solution Explorer deve estar assim:

    Antes do próximo passo precisamos lembrar alguns conceitos.

    1. A biblioteca AgendaTelefonica.OR receberá os arquivos de mapeamento de Objetos Relacionais do NHibernate. Funcionará como DTO´s, ou seja, este objetos trafegarão livremente entre as camadas levando e trazendo informações. Portanto todas as outras bibliotecas, inclusive o site que ainda vamos criar, precisam “ver” essa biblioteca.
    2. A biblioteca de interface – AgendaTelefonica.Interface – será utilizada na declaração dos DAO´s e dos BO´s. Inclusive essas intefaces tem uma utilidade importante que é desacoplar as camadas no sistema e ajudar na escalabilidade. Inclusive, instanciamento dos objetos das camadas deve ser através das suas intefaces. Isso garante o desacoplamento. Logo todas a camada de acesso a dados, negócio e a aplicação devem “ver” esta biblioteca.
    3. Uma hierarquia de acesso precisa ser obedecida na construção em camadas. A aplicação web ou desktop faz requisições somente à camada de negócio; representada pela biblioteca AgendaTelefonica.BO. As regras de negócios fazem requisições soment à camada de acesso a dados (AgendaTelefonica.DAO) que, por sua vez, acessa o banco de dados através de uma camada extra chamada Camada de Persistência que, no nosso sistemas, será responsabilidade do NHibernate. NUNCA e NUNCA MESMO, em camadas, essa hierarquia de acesso pode ser desobedecida. A camada superior faz requisições à cada imediatamente inferior e, esta, apenas responde as requisições. Em outras palavras, a camada superior executa um método de um objeto presente na camada inferior para realizar alguma operação e/ou receber alguma informação. Nunca ao contrário. Se em algum momento o DAO, por exemplo, fizer uma chamada ao BO, isso pode ser tudo. Menos arquitetura em camada. Ou se, a aplicação web fizer uma chamada diretamente ao DAO pulando o BO, ou se o BO fizer um acesso ao banco de dados diretamente pulando o DAO, ou mesmo, se o DAO fizer chamada diretamente ao banco pulando a camada de persistência, em qualquer uma das situações a aplicação perde a característica do que nos chamamos ARQUITETURA EM CAMADAS.

    No Visual Studio é possível garantir as hierarquia de camadas. Teremos que adicionar a referência de um projeto em outro segundo o que foi discutido nos itens acima:

    1. Em AgendaTelefonica.Interface adicionamos referência a AgendaTelefonica.OR;
    2. Em AgendaTelefonica.DAO adicionamos referência a AgendaTelefonica.OR e AgendaTelefonica.Interface;
    3. Em AgendaTelefonica.BO Adicionamos referência a AgendaTelefonica.OR, AgendaTelefonica.Interface e AgendaTelefonica.DAO;

    Lembre-se: OR e Interface estão em todas pelas suas características: Transferência de dados para OR e desacoplamento para Interface.

    Como nosso DAO utilizará o NHibernate voce deve adicionar em AgendaTelefonica.DAO referrência ao NHibernate também (localize a instalação que voce fez do RSClass – Gerador de Classes). Detalhe: adicione somente no DAO.

    Para adicionar uma referência a um projeto voce deve clicar no botão direto do mouse sobre o projeto e selecionar Add Reference… Selecione a aba Projects e faça as adições ao projeto atualmente selecionado.

    Depois de ter feito isso para cada projeto, adicione referência do NHibernate a AgendaTelefonica.DAO. Clique no projeto com o botão direito, Selecione Add Reference…, selecione a aba Browse e localize o arquivo NHibernate.dll na pasta de ‘Bibliotecas’ localizada na pasta de instalação do programa RSCLass – Gerador de Classes (esta instalação deve ter sido feita no primeiro post deste tutorial).

    Como todas as referências adicionadas o Solution Explorer deve se apresentar assim:

    Pronto. Mais uma etapa cumprida. Nosso ambiente está pronto. Vimos como criar uma aplicação em camadas no Visual Studio respeitando a hierarquia. Registrem comentários e dúvidas.

    Na página http://tutorialagendatelefonica.googlecode.com voce pode encontrar os arquivos deste tutorial gerados até aqui (PARTE II). No próximo post iremos começar a criar os arquivos de cada projeto, iniciando pelo OR.

    Até o próximo.

    Visual Studio + NHibernate: Construindo aplicações em camadas

    Devido a grande quantidade de dúvidas recebidas, decidi escrever um pequeno tutorial de como construir uma aplicação em camadas utilizando o NHibernate no Visual Studio. Vamos construir uma aplicação completa utilizando estes recursos e o conceito de camadas. Tentaremos fazer uso de alguns padrões de projeto para enriquecer nosso tutorial.

    Não vamos tratar de conceitos. Iremos apenas utilizar as ferramentas na aplicação dos mesmos. Na internet existe uma vasto conteúdo sobre os assuntos aqui relacionados. Também é importante que o leitor tenha conhecimento da utilização do Visual Studio já que não iremos explicar seu funcionamento detalhamente no desenvolvimento da nossa aplicação.

    Então vamos lá.

    Montagem de Ambiente

    Inicialmente vamos definir as configurações e requisitos para nosso trabalho:

    1. Ambiente de desenvolvimento: Visual Studio 2008 SP1 profissional com suporte a C#.
    2. Banco de dados: Firebird 2.1.3.18185.
    3. Ferramenta para administração do banco de dados: FlameRobin v0.9.3.1870 .
    4. Framework de persistência:  NHibernate v2.1.0 GA.
    5. RSCLass – Gerador de Classes. Baixe e instale esse programa. Ele irá gerar a maioria dos arquivos que iremos utilizar em nossa aplicação.

    Com tudo instalado e funcioando corretamente já podemos iniciar os trabalhos.

    O Problema

    Vamos imaginar o seguinte problema: a secretária do diretor não quer mais ser encomodada pelo resto da empresa, que toda hora liga para ela perguntando dados e telefones de clientes e pessoas em outras filiais. Ela explicou a situação para o diretor e ele concordou. O diretor então chamou o gerente de TI e determinou que ele resolvesse o problema.

    Especificação de Requisitos

    Após análise e discursão, chegou-se a conclusão que deveria existir na empresa uma Agenda Telefônica na intranet, para que todos possam acessar, cadastrar, alterar, consultar e listar contatos. Mas, para ter acesso a agenda, cada usuário precisaria de uma senha. Uma regra importante é que somente o usuário que incluio o contato pode ter a permissão para excluí-lo. Porém, todos podem alterar, listar e consultar quaquer contato registrado. Se um contato for definido como confidêncial, somente o usuário que cadastrou teria o direito a visualizar, modificar, consultar ou excluir. Se um usuário for excluído, seus contatos passam a ser de domínio público, ou seja, todos ganham o direito de gerenciar os contatos do usuário excluído.

    Vamos construir este sistema para WEB e em camadas.

    A Modelagem

    Fiz um pequeno diagrama do módelo conceitual do sistema.

    Como pode ser visto o sistema terá 4 classes: Usuario, Contato, Cidade e UF. UF compõe Cidade que, por sua vez, compõe Contato. Usuário gerencia o contato.

    Fiz também o diagrama de entidades relacionais.

    Todos os arquivos necessários para execução do tutorial podem ser encontrados em http://tutorialagendatelefonica.googlecode.com. Baixe o script do banco que foi gerado para o Firebird. Utilize o FlameRobim para criar o banco de dados e rodar o script ou, então, utilize um banco de dados e ferramenta administrativa de sua preferência.

    OK! O projeto foi definido e o banco está pronto. No próximo post utilizaremos o Visual Studio para definir a aplicação. Fique a vontade para comentar e registrar suas dúvidas até aqui.

    Próxima Página »


    Calendário

    Novembro 2009
    D S T Q Q S S
    « Jul    
    1234567
    891011121314
    15161718192021
    22232425262728
    2930  

    Desde (04/11/07)

    • 43,992 visitas