NHibernate: sugestão de arquitetura para uma aplicação CRUD

Publicado por Marcos Dell Antonio em 22/03/2007 | .NET

Antes de tudo, CRUD é um acrônimo para Create, Read, Update e Delete. Logo, uma aplicação CRUD nada mais é do que uma aplicação simples e que executa basicamente estas operações.

Para um projeto simples usando o NHibernate, sem uma regra de negócios muito complexa, a arquitetura abaixo serve perfeitamente:

É uma única solução com três projetos: a interface (Site), a camada de acesso a dados (DAL - Data Acess Layer) e o mapeamento objeto/relacional (DTO - Data Transfer Object, alguns chamam de VO - Value Object também). Veja abaixo uma breve descrição sobre eles.

- Site: aqui deve ficar toda a apresentação do sistema, ou seja, as páginas ASPX, o code-behind, o Web.Config, imagens, etc. A pasta App_Data não é necessária, só mantive ela pois foi criada automaticamente com o site.

- DAL: por ser a camada de acesso a dados, todos os acessos ao banco serão feitos por ela (usando o NHibernate, claro). Ao salvar uma informação, por exemplo, deverá ser usado algum método de uma classe pertencente a este projeto, e não o NHibernate diretamente ou um comando SQL (argh).

- DTO: todo o mapeamento objeto/relacional ficará dentro deste projeto. Não esqueça de definir os arquivos hbm.xml como Embedded Resource, caso contrário ficarão inacessíveis aos outros projetos. As classes, como de costume, deverão ser marcadas como Serializable.

Um breve exemplo:

Dentro do Site temos um cadastro de atividades devidamente mapeado no DTO: Atividade.hbm.xml e Atividade.cs.

No DAL deve haver uma outra classe chamada AtividadeDAL, que será responsável por inserir, buscar, atualizar e remover atividades.

Aqui vale uma observação: como os métodos CRUD do NHibernate (Save, Update, Delete e Get) recebem como parâmetro um object, recomendo a criação de uma classe BaseDAL que será herdada por todas as outras. Algo mais ou menos assim:

namespace DAL { public class BaseDAL { public static void Save(object o) { // Salva o objeto usando o NHibernate } } }

E a AtividadeDAL herda dela:

namespace DAL { public class AtividadeDAL : BaseDAL { // O método save já está disponível na BaseDAL } }

Quando o usuário clicar na opção para salvar uma atividade, o código abaixo será executado:

Atividade atividade = new Atividade(); atividade.Id = ...; atividade.Descricao = ...; AtividadeDAL.Save(atividade);

Veja que o objeto definido no DTO é carregado e é salvo pela classe DAL.

Para saber mais sobre o NHibernate, veja o artigo que escrevi sobre como criar uma aplicação Web em C# usando o NHibernate.

Hope this helps (by ScottGu).

Até +.

7 comentários

  1. 1
    João Guilherme Pugsley // June 2nd, 2007 at 11:14 pm

    Estou fazendo meu TCC em C#, mas estou tendo dificuldades em conectar o mygeneration com o mysql. Apresenta a seginte mensagem:
    [System.NullReferenceException] - Object reference not set to an instance of an object.

    Você sabe como posso resolver esse problema?

  2. 2
    Marcos Dell Antonio // June 2nd, 2007 at 11:25 pm

    Você instalou o provider do MySQL?

    Provavelmente o MyGeneration não está conseguindo achar a DLL do provider no GAC.

    T+

  3. 3
    Douglas // June 13th, 2007 at 11:11 am

    Olá Marcos,
    Achei a sua proposta de arquitetura muito legal.
    Porém tenho uma dúvida com relação aos métodos staticos na camada DAL, isso não pode causar um gargalo na aplicação?

    Douglas

  4. 4
    Marcos Dell Antonio // June 13th, 2007 at 12:01 pm

    Olá Douglas.

    Que tipo de gargalo? Não entendi.

    Eu tentei centralizar os acessos ao banco em métodos estáticos só para facilitar. ;)

    Você até pode por o Save(), Update(), etc, dentro da classe de mapeamento, mas se vc utiliza o MyGeneration para gerá-la, por exemplo, corre o risco de perder suas implementações quando for gerar a classe novamente e já tiver os métodos.

    Até +.

  5. 5
    Joao Batista // September 10th, 2007 at 11:41 pm

    João Guilherme Partindo da obs do Marcos, sobre o erro [System.NullReferenceException] - Object reference not set to an instance of an object:

    Copie o mysql.data.dll para a pasta do myGeneration. Comigo resolveu

    O instalador creio que tenha registradado no gac. Pelo Visual Studio abria normalmente com o conector.
    Para o Mygeneration copiar para a pasta do .exe solucionou.

    A propostito, como instalo e desinstalo manualmente do gac?

  6. 6
    Marcos Dell Antonio // September 15th, 2007 at 1:24 am

    Acho que isso aqui resolve a sua dúvida Joao:

    http://support.microsoft.com/kb/315682/pt

    T+

  7. 7
    Leandro // November 20th, 2007 at 7:36 am

    Ola …

    Estou desenvolvendo um aplicativo cliente-servidor de medio porte utilizando o NHibernate. As classes que recebem o mapeamento do NHibernate foram chamadas de BO. O fato é que eu ainda não consegui uma forma viavel de serializar os meus objetos BO para envialos do aplicativo cliente para o aplicativo servidor. O NHibernate acaba inserindo uma serie de controles que não são serializaveis dentro da minha classe, como proxys. A primeira alternativa que eu vi foi tentar utilizar DTO’s, mas eu não a vejo como uma solução denitiva pois dificulta a manutenção do sistema alem de aumentar a quantidade de codigo criado (devo ter um dto para cada objeto de negocio, mais codigo para efetuar o parsing). Do meu ponto de vista a melhor solução seria pegar a minha classe BO, eliminar os controles do NHibernate e envia-la para a aplicação cliente. Aparentemente parece uma solução facil, mais o fato é que existem algumas questões bem complexas que eu ainda não consequi resolver: 1) como tratar as associações Lazy de forma a otimizar a performa-se do aplicativo. Se não for tamado o devido cuidado a aplicação pode acabar lendo todas as tabela do banco; 2) como evitar referencia circular; 3) Como otimizar as coleções; 4) Como efetuar o merge entre um dado vindo do aplicativo cliente e uma classe BO. São perguntas que estão me fazendo perder os cabelos… alguem tem alguma ideia?

Deixe o seu comentário

Anúncios

Anúncio provido pelo BuscaPé