Arquivo para Agosto, 2008

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 na sua aplicação, enquanto no web site não tem como impedir diretamente. Enfim, veja o que é melhor. Fiquei com web application… Adicionei projeto web application com nome “AgTel”. 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.

Clique aqui e baixe as bibliotecas. Vai junto também o web.config para quem tiver alguma dúvida. Após download e descompactação (renomei antes de descompactar para .ZIP), salve junto com as outras que utilizamos anteriormente. No projeto adicione as duas novas bibliotecas como referência no projeto. 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. 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 ;)

Se tudo foi feito corretamente teremos a seguinte tela:

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 MyGeneretion e um dos nossos scripts 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 utilizar o script “WebFormTabela.csgen“. Utilize este script no MyGeneration e gere os arquivos na pasta do projeto web. Selecione UF dentre as tabelas do banco.

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 TabelaUf.aspx com o botão direito do mouse e selecione “Convert to Web Application“. Defina a página TabelaUf.aspx como “Set As Start Page” e execute a aplicação. Vamos ver se funciona…

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

  1. Se voce baixou as atualizações dos scripts e bibliotecas do post anterior e está utilizando, terá que gerar os DAO´s novamente. ATENÇÃO: NÃO GERE POR CIMA. APAGUE-OS E GERE NOVAMENTE.
  2. No projeto AgTel adicione referencia à bilbioteca do Firebird (FirebirdSql.Data.FirebirdClient.dll) que pode ser conseguida diretamente no site do Firebird. Após a adição, clique com botão direito do mouse sobre a referência adicionada e selecione “Properties”. Modifique a propriedade “Copy Local” para true. Se voce utilizar outro banco deve fazer a mesma coisa: adicionar o client do seu banco ao projeto. Sendo SQL Server ou Oracle isso não será necessário. Na realidade, este passo depende do banco que voce está utilizando e a forma que voce configurou o Hibernate para acessar este banco.
  3. No projeto BO é necessário adicionar referência de duas bibliotecas: Regisoft.dll e Regisoft.Camadas.Interface.dll
  4. No projeto AgTel crie uma pasta chamada Diversos. Nesta pasta voce deve utilizar o MyGeneration com o script BOAccess Class for Nhibernate.csgen para gerar a classe de acesso aos DAO´s. Durante a geração da classe pelo MyGeneration: em using escreva AgendaTelefonica.OR e em namespace escre AgTel. No Visual Studio selecione o arquivo e “Include In Project“.  Mas este script possui alguns erros que só identifiquei enquanto preparava este post. No post anterior, os arquivos para download foram substituídos por versões corrigidas.
  5. No arquivo TabelaUf.aspx.cs adicione na seção de using: using AgendaTelefonica.BO;
  6. Substitua a linha 46 por IList<Uf> lst = BOAccess.getBOFactory().UfBO().Listar(“Sigla”);
  7. Substitua a linha 91 por o = bo.UfBO().InserirAlterar(o, op);
  8. Substitua a linha 129 por BOAccess.getBOFactory().UfBO().Excluir(lst); Essas 03 últimas modificação removem a informação de usuário dos parâmetros de entrada dos métodos. Essa informação serviria para que, na regra de negócio, houvesse validação de permissões do usuário. Removi apenas para fins de testes na página.
  9. Comente a linha 26, 27 e 28, também removendo informação de login de usuário. Eu guardo a informação de login na sessão. Quando a sessão expira o usuário deve efetuar login novamente.;
  10. Para nosso exemplo, foi necessário fazer modificações no script do banco. Um novo script foi substituído no primeiro post dessa série. Nada muito complexo. Apenas incluí dois Generator no banco: Um para auto-numeração do cadastro de cidades e outro para auto-numeração do cadastro de UF.

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:

/// <summary>
/// Selecionar uma UF através da sigla
/// </summary>
/// <param name=”sigla”>Sigla para pesquisa</param>
/// <returns></returns>
public Uf SelecionarPorSigla(string sigla)
{
ICriteria crit = getCriteria()
.Add(Expression.Eq(“Sigla”, sigla));
return crit.UniqueResult<Uf>();
}
/// <summary>
/// Listar UF´s que iniciem por uma string
/// </summary>
/// <param name=”descricao”>Descrição inicial para filtro</param>
/// <returns></returns>
public IList<Uf> ListarPorDescricao(string descricao)
{
string hql = @”select uf from Uf uf
where uf.Descricao like :descricao
order by uf.Descricao”;
IQuery query = getSession().CreateQuery(hql);
query.SetAnsiString(“descricao”, descricao + “%”);
return query.List<Uf>();
}

Veja que criamos dois métodos DAO´s comentados. Um com critéria e outro com HQL (Hibernate Query Language). Veja que o controle da sessão do Hibernate vem do getSession() e o critéria vem do getCriteria(). 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);

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);

Note que algumas linhas já estão lá definidas assim como no UfBO.cs. Essas linhas foram adicionadas pelos scripts do MyGenerator.

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: existe um script chamado WebFormCadastro.csgen que gera um outro layout de página que foi desenhado para utilizar essas pesquisas. Após a geração dos códigos algumas modificações como fizemos na nossa página serão necessárias.

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

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.


Calendário

Agosto 2008
D S T Q Q S S
« Jul   Jan »
 12
3456789
10111213141516
17181920212223
24252627282930
31  

Desde (04/11/07)

  • 43,583 visitas