Dev (Back & Front)ARTIGO

ASP .NET: Usando o NHibernate em uma aplicação Web – Parte 02

Na
primeira parte deste artigo, foram
realizadas as seguintes tarefas:

  • Definição do banco de dados
    Macoratti.mdf e da tabela Usuarios;
  • Criação do projeto no Visual Web Developer 2010
    Express;
  • Referência ao NHibernate no
    Projeto ASP NET;
  • Criação da classe de negócio
    Usuario;
  • Definição dos arquivos de
    mapeamento e configuração do NHibernate.

Já temos portanto tudo pronto para usar os recursos do NHibernate em nossa
aplicação ASP .NET e realizar as operações CRUD relacionadas com as manutenção
das informações da tabela Usuario. Nossa próxima tarefa é definir uma sessão NHibernate.

Mas afinal o que vem a ser uma sessão NHibernate?

Pense em uma sessão NHibernate como uma ligação abstrata ou virtual de um
conduto ou fio com o banco de dados. Quando se usa o NHibernate, não temos que nos preocupar em criar uma conexão,
abrir a conexão, passar a conexão para o objeto Command e criar um DataReader a
partir do objeto Command etc.

Com o NHibernate, o tratamento é diferente. Temos que solicitar um objeto
Session para o SessionFactory e usar a sessão para realizar as
operações CRUD.

O NHibernate trabalha com um mecanismo de sessão, e para criar uma sessão
usamos um objeto do tipo ISessionFactory do NHibernate. Além de criar a sessão, devemos tomar o cuidado de ela ser inicializada
apenas uma única vez durante a sessão do usuário na aplicação WEB para evitar
degradação no desempenho da aplicação.

Para isso, vamos definir uma classe chamada NHibernateHelper no
projeto. No menu Project, selecione o item Add Class, selecione o template
Class e informe o nome NHibernateHelper.vb. A seguir, vamos definir o seguinte código nesta classe:

Imports NHibernate<br /><br />Imports NHibernate.Cfg<br /><br />Public Class NHibernateHelper<br /><br />    Private Shared <strong>_sessionFactory</strong> As ISessionFactory<br /><br />    Private Shared ReadOnly Property <strong>SessionFactory()</strong> As ISessionFactory<br /><br />        Get<br />            'se a sessão não existir cria e retorna uma sessão<br /><br />            If _sessionFactory Is Nothing Then<br /><br />                Dim configuration = New Configuration()<br /><br />                configuration.Configure()<br /><br />                configuration.AddAssembly(GetType(Usuario).Assembly)<br /><br />                _sessionFactory = configuration.BuildSessionFactory()<br /><br />            End If<br /><br />            Return <strong>_sessionFactory</strong><br /><br />        End Get<br /><br />    End Property<br /><br />    Public Shared Function OpenSession() As ISession<br /><br />        Return SessionFactory.OpenSession()<br /><br />    End Function<br /><br />End Class

Note que temos a variável estática (shared) e privada _sessionFactory 
do tipo ISessionFactory. É através desse objeto que iremos criar as sessões NHibernate, e como ele é
estático garantimos que a sessão será criada uma única vez.

O método SessionFactory é o método principal da classe, sendo o
responsável por criar o ISessionFactory e
retorná-la. No código, verificamos se não existe uma sessão criada e, em caso positivo,
criamos a sessão.

Na primeira execução do código, teremos que criar o
ISessionFactory e para isso temos que recuperar as configurações do
arquivo de configuração do NHibernate através do método Configure() da
classe Configuration.

Em seguida, registramos os arquivos de mapeamento através do método
AddAssembly que usa o nome do Assembly onde estão os arquivos de mapeamento
do NHibernate.

O método OpenSession() cria o SessionFactory e retorna um
objeto ISession que representa a sessão NHibernate.

Agora vamos criar uma interface no projeto onde iremos definir os métodos que
iremos usar na aplicação: no menu Project -> Add Class, informe o nome IUsuarioRepositorio.vb
e clique em Add.

A seguir defina o seguinte código nesta interface:

Imports System.Collections.Generic<br /><br /><br />Public Interface IUsuarioRepositorio<br /><br /><br />Sub Add(ByVal product As Usuario)<br /><br />Sub Update(ByVal product As Usuario)<br /><br />Sub Remove(ByVal product As Usuario)<br /><br />Function GetById(ByVal id As Guid) As Usuario<br /><br />Function GetByLogin(ByVal login As String) As Usuario<br /><br />Function getAllUsuarios()<br /><br />Function GetByPerfil(ByVal perfil As String) As ICollection(Of Usuario)<br /><br /><br />End Interface

Apenas para lembrar: em uma interface definimos apenas as assinaturas dos
métodos que deverão ser implementados por quem for implementar a interface.

Para implementar a interface, vamos criar uma classe concreta: No menu
Project -> Add Class, informe o nome UsuarioRepositorio.vb e clique
em Add.

A seguir, vamos definir o código que vai implementar cada um dos métodos
definidos na interface:

Imports NHibernate<br /><br />Imports NHibernateASPNET<br /><br />Imports NHibernate.Criterion<br /><br />Public Class UsuarioRepositorio<br /><br />    Implements IUsuarioRepositorio<br /><br /><strong>Public Sub Add(ByVal usuario As Usuario) Implements IUsuarioRepositorio.Add</strong><br /><br />        Using session As ISession = NHibernateHelper.OpenSession()<br /><br />            Using transaction As ITransaction = session.BeginTransaction()<br /><br />session.Save(usuario)<br /><br />transaction.Commit()<br /><br />            End Using<br /><br />        End Using<br /><br />    End Sub<br /><br /><br /><br /><strong>Public Function GetById(ByVal id As System.Guid) As Usuario Implements IUsuarioRepositorio.GetById</strong><br /><br />        Using session As ISession = NHibernateHelper.OpenSession()<br /><br />Return session.[Get](Of Usuario)(id)<br /><br />        End Using<br /><br />    End Function<br /><br /><br /><br /><strong>Public Function GetByLogin(ByVal login As String) As Usuario Implements IUsuarioRepositorio.GetByLogin</strong><br /><br />        Using session As ISession = NHibernateHelper.OpenSession()<br /><br />            Dim product As Usuario = session.CreateCriteria(GetType(Usuario)).Add(Restrictions.Eq("Login", login)).UniqueResult(Of Usuario)()<br /><br />            Return product<br /><br />        End Using<br />    End Function<br /><br /><br /><br /><strong>Public Sub Remove(ByVal usuario As Usuario) Implements IUsuarioRepositorio.Remove</strong><br />       Using session As ISession = NHibernateHelper.OpenSession()<br /><br />            Using transaction As ITransaction = session.BeginTransaction()<br /><br />session.Delete(Usuario)<br /><br />transaction.Commit()<br /><br />            End Using<br /><br />        End Using<br /><br />    End Sub<br /><br /><br /><br /><strong>Public Sub Update(ByVal usuario As Usuario) Implements IUsuarioRepositorio.Update</strong><br /><br />        Using session As ISession = NHibernateHelper.OpenSession()<br /><br />            Using transaction As ITransaction = session.BeginTransaction()<br /><br />session.Update(Usuario)<br /><br />transaction.Commit()<br /><br />            End Using<br /><br />        End Using<br /><br />    End Sub<br /><br /><strong>Public Function getAllUsuarios() As Object Implements IUsuarioRepositorio.getAllUsuarios</strong><br /><br />        Using session As ISession = NHibernateHelper.OpenSession()<br /><br />            Dim usuarios As IList = session.CreateCriteria(GetType(Usuario)).List()<br /><br />            Return usuarios<br /><br />        End Using<br /><br />    End Function<br /><br /><strong>Public Function GetByPerfil(ByVal perfil As String) As System.Collections.Generic.ICollection(Of Usuario) Implements IUsuarioRepositorio.GetByPerfil</strong><br /><br />        Using session As ISession = NHibernateHelper.OpenSession()<br /><br />            Dim usuarios = session.CreateCriteria(GetType(Usuario)).Add(Restrictions.Eq("Perfil", perfil)).List(Of Usuario)()<br /><br />            Return usuarios<br />        End Using<br />    End Function<br /><br /><br />End Class

Destaques:

  • Note que usamos a palavra-chave implements
    e o nome da interface que vamos implementar;
  • Em cada requisição de uma sessão estamos usando
    o recurso Using, de forma que o recurso usado é liberado ao término da
    utilização;
  • As transações que envolvem atualização no banco
    de dados usam transações.

Neste momento, a nossa solução deverá ter a seguinte estrutura:

Eu optei criar as classes e os arquivos de configuração em um mesmo projeto e no mesmo local. Fiz isso porque o projeto é bem simples e para tornar mais fácil a visualização da estrutura.

Para projetos maiores, é aconselhável criar pastas distintas para as classes e para os arquivos de configuração no mesmo projeto. Pode-se ainda criar projetos distintos para dividir a solução em camadas o que está mais aderente às boas práticas.

Agora só falta definirmos a interface da aplicação que será a página ASP
.NET Default.aspx e usar os recursos que criamos até aqui no projeto.

Referências:

é referência em Visual Basic no Brasil e autor dos livros "Aprenda Rápido: ASP" e "ASP, ADO e Banco de Dados na Internet". Mantenedor do site macoratti.net.

Ver perfil