Desenvolvimento - C#

Criando uma aplicação Web em C# usando o NHibernate

O autor apresenta neste artigo como criar uma aplicação web totalmente orientada a objetos usando o framework NHibernate e a linguagem C#.

por Marcos Dell Antonio



Apresento neste artigo como criar uma aplicação web totalmente orientada a objetos usando o framework NHibernate e a linguagem C#.

Nossa meta é construir um website com um cadastro de atividades usando os novos controles GridView e ObjectDataSource, ambos presentes no Framework .NET 2.0. A aplicação possuirá as funcionalidades básicas de um cadastro, sendo elas: consultar, inserir, editar e remover. Um detalhe muito importante é que nenhuma linha de código SQL será escrita devido ao uso do NHibernate.

Para desenvolver esta aplicação vamos usar as seguintes ferramentas:

- Visual Studio 2005 (pode ser o Visual Web Developer 2005 Express Edition)
Link: http://msdn.microsoft.com/vstudio/express/vwd/

- MySQL 5.0 Community Edition
Link: http://dev.mysql.com/downloads/mysql/5.0.html

- MySQL Connector 1.0.7: provider pra acessar o MySQL
Link: http://dev.mysql.com/downloads/connector/net/1.0.html

- MyGeneration 1.1.5.1: ferramenta para gerar o mapeamento objeto/relacional para o NHibernate
Link: http://www.mygenerationsoftware.com

- NHibernate 1.0.2: framework para persistência dos objetos
Link: http://www.nhibernate.org

- Instalação e configuração das ferramentas

Depois de fazer o download de todas as ferramentas citadas acima, instale o MySQL, crie um banco de dados chamado WebAppOO e uma tabela chamada Atividade com os seguintes campos:

- Id - Int (primary key)
- Nome - Varchar(50), Not null
- Descrição - Varchar(200), Not null

Deve ficar assim:

Agora instale o provider do MySQL e o MyGeneration. Não vou cobrir a configuração do MyGeneration, para isso veja nas referências desse artigo a documentação sobre o assunto.

O próximo passo é descompactar o NHibernate em uma pasta qualquer.

- Criando a aplicação

Abra o Visual Studio e crie uma nova solução chamada ProjetoWeb. Para isso, clique em File - New - Project - Other Project Types - Visual Studio Solutions e escolha o template Blank Solution. Chame a solução de ProjetoWeb e defina a localização (de preferência a mesma do artigo). Veja:

Clique no botão OK e uma solução vazia será criada. Agora crie um website, clicando com o botão direito do mouse sobre a solução recém criada, escolha Add - New Web Site. Deixe selecionado o template ASP.NET Web Site e na localização coloque c:\ProjetosVS\ProjetoWeb\WebAppOO. Deve ficar da seguinte forma:

Clique em OK para criar o website. Agora vamos montar a nossa interface. Deixe o arquivo Default.aspx com a seguinte aparência:

Os controles mais importantes são o GridView e o ObjectDataSource. Repare que somente adicionei os controles na tela e configurei o nome deles, ainda não fiz nenhuma ligação entre eles. O hyperlink Inserir Atividade aponta para o arquivo InserirAtividade.aspx. - Web.config

Após ter criado a aplicação, precisamos adicionar o arquivo Web.config. Nele ficarão as configurações do website e também as do NHibernate. Para isso, clique com o botão direito sobre o projeto e selecione Add New Item. Escolha o template Web Configuration File e clique em Add.

Abra o arquivo Web.config que acabou de ser adicionado e procure pelo item configuration. Logo após ele, adicione as seguintes linhas:

Todo esse código acima é referente a configuração do NHibernate. Se por acaso pretendermos mudar o banco de dados da aplicação, basta alterar algumas das linhas acima.

- Mapeamento objeto/relacional

Como mencionado anteriormente, não vou entrar em detalhes sobre o MyGeneration. Uma documentação detalhada sobre ele pode ser encontrada nas referências desse artigo.

Faremos o mapeamento em um outro projeto, chamado MapeamentoOR. Para isso, clique com o botão direito sobre a Solution, escolha Add - New Project, selecione o template Class Library, digite o nome MapeamentoOR e defina o campo Location para C:\ProjetosVS\ProjetoWeb. Veja como deve ficar:

Clique em OK e logo que o projeto MapeamentoOR for criado, remova o arquivo Class1.cs que ele gerou automaticamente.

Veja abaixo os arquivos .hbm.xml e .cs que compõem o mapeamento da tabela Atividade.

Atividade.hbm.xml

Atividade.cs (perceba que a classe está marcada como Serializable)

A declaração das propriedades Nome e Descricao simplesmente implementam o get e set para a respectiva variável private. Tome como exemplo a propriedade Id. Ambos os arquivos foram gerados com o MyGeneration. Entretanto, fiz algumas alterações após a geração, como por exemplo, as checagens nos métodos get e set. A princípio isso não é necessário. Somente as fiz para poder mostrar o código aqui, caso contrário ficariam gigantes.

Os dois arquivos devem ser adicionados ao projeto MapeamentoOR e o Atividade.hbm.xml deve ter a propriedade Build Action configurada para Embedded Resource. Para isso, clique com o botão direito sobre ele no Solution Explorer e escolha Properties. Logo abaixo aparecerão as propriedades desse arquivo. Configure-as desta forma:

O projeto MapeamentoOR deve estar da seguinte maneira:

Se tudo estiver correto, efetue o Build clicando com o botão direito sobre MapeamentoOR e escolhendo a opção Build. Depois disso, uma dll chamada MapeamentoOR.dll será gerada.

No projeto principal (WebAppOO), vamos adicionar uma referência à dll gerada. Clique com o botão direito sobre ele e escolha Add Reference. Navegue até a aba Projects e lá estará a dll do projeto MapeamentoOR. Veja:

Selecione essa dll e clique em OK. A partir de agora poderemos acessar o mapeamento objeto/relacional de dentro do website WebAppOO.

- Classe Helper para o NHibernate

Como o NHibernate será acessado várias vezes pela nossa aplicação, nada mais sensato do que criar uma classe com métodos para facilitar o nosso trabalho. Para a aplicação em questão, precisamos somente de um método: GetSession(). Ele nos retornará uma sessão com o NHibernate, que corresponde a uma conexão com o banco de dados.

Além de facilitar nossa vida nas chamadas ao NHibernate, essa classe será responsável por manter na memória somente uma instância do mapeamento objeto/relacional. De acordo com a documentação do próprio framework, o processo de carga do mapeamento é muito pesado, portanto recomenda-se que somente uma instância do mesmo seja compartilhada entre as requisições.

Tendo em vista esse problema, logo nos surge a idéia de usar um dos vários padrões de projeto, o Singleton. A finalidade desse padrão é permitir que somente uma instância de determinada classe esteja na memória.

Antes de criar a classe helper, precisamos adicionar uma referência ao arquivo NHibernate.dll ao WebAppOO. Para isso, clique com o botão direito sobre o projeto WebAppOO e selecione Add Reference. Navegue até a pasta onde o NHibernate foi descompactado, procure pela pasta bin e dentro desta procure pelo arquivo NHibernate.dll. Clique em OK.

Após adicionar essa referência, o projeto deve ter ficado da seguinte forma:

Repare que outras dlls foram adicionadas junto com a do NHibernate.

Agora adicione um novo arquivo ao projeto WebAppOO (dentro da pasta App_Code) chamado NHibernateHelper.cs.

Veja o código:

A classe NHibernateHelper provê um método chamado GetSession(). Sua implementação garante que somente uma instância do SessionFactory será criada. - Camada de acesso a dados

Vamos adicionar um novo arquivo ao projeto: AtividadeDAO.cs. Esse arquivo possui métodos responsáveis por inserir, selecionar, alterar e remover uma atividade. Todos os métodos dessa classe vão trabalhar com objetos, ou seja, para inserir uma atividade, por exemplo, não será usada uma query SQL, mas sim uma funcionalidade do NHibernate que recebe um objeto e gera a query.

Adicione o arquivo AtividadeDAO.cs na pasta App_Code do projeto WebAppOO. Assim que ele for criado, já inclua os namespaces System.Collections, NHibernate e MapeamentoOR na sessão using.

Agora vamos codificar todos os métodos necessários à classe AtividadeDAO. Vamos precisar dos seguintes métodos:

- RetornaAtividades(): retorna todas as atividades cadastradas na tabela Atividade. Ele recebe três parâmetros: column, maximumRows e startRowIndex. O primeiro serve para executar a ordenação e os dois últimos a paginação. Código:

Vale a pena ressaltar que a variável sql não está recebendo um comando SQL, mas sim HQL, que é próprio do NHibernate. Logo, poderia ter sido chamada de hql ao invés de sql.

- SalvaAtividade(): recebe como parâmetro um objeto do tipo Atividade e salva ele usando o NHibernate. Código:

- RetornaAtividade(): recebe como parâmetro a Id de uma atividade a ser retornada. Código:

- ExcluirAtividade(): recebe como parâmetro uma atividade a ser excluída e exclui ela. Código:

- AtualizaAtividade(): atualiza uma atividade recebida por parâmetro. Código:

- Ligação dos controles da interface com a camada de acesso a dados

Depois de implementados os métodos da classe AtividadeDAO, vamos configurar os controles da interface (arquivo Default.aspx). Veja abaixo a configuração de cada controle:

GridView
- ID = _grdAtividades
- AllowPaging = true (habilita a paginação);
- PageSize = 5 (configura a paginação para 5 registros por página);
- AllowSorting = true (habilita a ordenação);
- DataSourceID = _odsAtividades;
- Na Smart Tag (aquela setinha no canto superior-direito da grid), selecione Enable Selection para mostrar o botão Select para cada linha da grid.

ObjectDataSource (se ao alterar alguma propriedade desse controle você for questionado para recriar os campos da grid, seleciona Não. Provavelmente isso vai acontecer ao alterar a DataSourceID)
- Name = _odsAtividades;
- EnablePaging = true (habilita a paginação);
- TypeName = AtividadeDAO (nome da classe que provê os métodos para selecionar, inserir, remover e atualizar os dados);
- SelectMethod = RetornaAtividades (nome do método da classe AtividadeDAO que retorna todas as atividades cadastradas);
- SortParameterName = column (nome do parêmetro do método RetornaAtividades que será usado para a ordenação dos registros);
- MaximumRowsParameterName = maximumRows (nome do parâmetro do método RetornaAtividades que representa o número máximo de linhas que serão mostradas por página. Não precisa alterar o valor dessa propriedade, pois ela já vem configurada por padrão);
- StartRowIndexParameterName = startRowIndex (nome do parâmetro do método RetornaAtividade que representa o primeiro registro da consulta que será mostrado. Não precisa alterar o valor dessa propriedade, pois ela já vem configurada por padrão).

Após essas configurações, já podemos executar pela primeira vez a aplicação. Clique com o botão direito sobre a Solution e escolha Build Solution. Assim que o Build acabar, execute o projeto. Eu executei no modo debug e apareceu uma mensagem me informando que o modo debug não estava habilitado no Web.config. Logo, deixei marcada a opção Modify the Web.config file to enable debugging e cliquei em OK.

Vejam o resultado da execução:

Logicamente nenhuma atividade foi listada, pois não há nenhuma cadastrada.

Criamos até agora toda a estrutura do site e a função consultar. Faltam ainda três: inserir, editar e excluir. - Inserir atividade

O cadastro de atividades será realizado em um arquivo chamado InserirAtividade.aspx, que é o mesmo que foi referenciado no hyperlink Inserir Atividade.

Adicione um novo Web Form ao projeto WebAppOO com o nome InserirAtividade.aspx. Após adicioná-lo, clique com o botão direito sobre o Default.aspx e defina ele como a página inicial clicando em Set As Start Page, caso contrário, a aplicação será iniciada pelo InserirAtividade.aspx.

Configure sua aparência da seguinte forma:

Repare novamente que não fiz nenhuma configuração em especial, somente alterei a ID dos controles e o Text.

Agora vamos implementar os eventos relacionados ao botão Salvar e Cancelar. Antes disso, adicione o using MapeamentoOR.

No botão cancelar, basta dar um duplo clique sobre ele e adicionar o seguinte código ao evento Click:

No botão Salvar, também com um duplo clique, adicione o seguinte código ao evento Click:

Pronto! Aí está o nosso cadastro de atividades. Rode a aplicação e clique no link Inserir Atividade. Cadastre algumas atividades e veja o resultado:

Com algumas atividades cadastradas, já podemos ver as funções de paginação e ordenação implementadas anteriormente. Clique sobre os campos (Id, Nome ou Descrição) para ordenar ou sobre os números no canto inferior/direito para mudar de página.

- Editar e excluir uma atividade

O processo para editar uma atividade é semelhante ao de inserir. Para facilitar as coisas, vou usar outro arquivo chamado EditarAtividade.aspx. Entretanto, acho que a forma mais correta de fazer isso seria usando um mesmo arquivo para inserir e editar, afinal os campos sempre serão os mesmos.

Desta forma, adicione outro Web Form a nossa aplicação e chame-o de EditarAtividade.aspx. Após a criação deste web form, adicione o using MapeamentoOR a ele.

Novamente, defina o Default.aspx como a página inicial (botão direito sobre o arquivo Default.aspx e selecione a opção Set As Start Page).

A interface do EditarAtividade.aspx deve ficar desta forma:

Repare que eu copiei e colei os mesmos controles do InserirAtividade.aspx e adicionei somente um botão para excluir a atividade em questão. Também defini a cor do TextBox código para uma cor diferente das demais e sua propriedade ReadOnly está como true. Fiz isso, pois, logicamente, a chave primária do cadastro não poderá ser alterada.

Vamos às implementações dos botões:

- No botão cancelar, duplo clique sobre ele e adicione o seguinte código ao evento Click:

- No botão Salvar, duplo clique sobre ele e o código do evento Click é este:

- E, finalmente, no botão excluir, duplo clique sobre ele e o código do evento Click é o este:

Agora que já temos os códigos de todos os botões implementados, ficou faltando somente um detalhe: como que vou selecionar a atividade que eu desejo editar ou excluir?

Se você percebeu, existe um botão na grid chamado Select (inclusive esse nome pode ser personalizado). Até agora não falei sobre ele, pois não era o momento. Esse botão será programado para funcionar da seguinte maneira: assim que o usuário clicar sobre ele, será redirecionado para o arquivo EditarAtividade.aspx. Para que isso seja possível vamos implementar o evento SelectedIndexChanged da nossa grid (no arquivo Default.aspx). Clique com o botão direito sobre a grid, selecione Properties e de um duplo clique no evento SelectedIndexChanged (tome cuidado para não clicar no SelectedIndexChanging que tem uma função totalmente diferente). Este evento deverá ser implementado da seguinte forma:

O SelectedIndexChanged será disparado sempre que o usuário clicar no botão selecte de uma das linhas da grid. Ao entrar no evento, ele pega a linha que o usuário clicou e o redireciona para a página de edição de atividades, que é a EditarAtividade.aspx. Veja que a Id da atividade selecionada (row.Cells[1].Text) é passada como parâmetro, por tanto no arquivo EditarAtividade.aspx é possível carregar uma atividade para ser editada. Para que isso aconteça, abra o EditarAtividade.aspx e de um duplo clique no web form (alguma parte que não tenha nenhum controle). O evento Page_Load que foi criado deverá possuir a seguinte implementação:

Este evento simplesmente carrega a atividade no form para ser editada ou excluída. O método CarregaAtividade deve estar implementado nesse mesmo arquivo da seguinte forma:

É isso! Nosso website com as funções de consultar, inserir, remover e editar está pronto. Para ver como ficou, rode a aplicação e navegue através dos links Select e Inserir Atividade.

- Conclusão

Esse artigo foi inspirado pelos dias de estudo dedicados à plataforma .NET. Depois de passar alguns dias procurando a receita de bolo para como construir um website da melhor maneira possível, cheguei à conclusão que existem várias formas de alcançar esse objetivo. Como dizia Raul Seixas:

"Já fui católico, budista, protestante,
Tenho livros na estante, todos têm explicação."

Em outras palavras, todo mundo defende a sua maneira de pensar, pena que nenhuma delas envolvia NHibernate e ObjectDataSource.

Enfim, caso tenham alguma dúvida sintam-se a vontade para entrar em contato.

- Referências

NHibernate - Guia inicial
Link: http://www.linhadecodigo.com.br/artigos.asp?id_ac=546

Hibernate 3 - Introdução
Link: http://www.guj.com.br/java.tutorial.artigo.174.1.guj

Hibernate 3 - Avançado
Link: http://www.guj.com.br/java.tutorial.artigo.181.1.guj

MyGeneration - Geração do mapeamento objeto/relacional
Link: http://www.linhadecodigo.com.br/artigos.asp?id_ac=914

- Download do código fonte

ProjetoWeb.rar

Marcos Dell Antonio

Marcos Dell Antonio - Profissional certificado (MCPD, MCTS e MCP) em tecnologias da Microsoft e especialista em .NET e Visual Studio Team System. Site: www.marcosdellantonio.net.