Mar 22 2007

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

Autor: Marcos Dell Antonio - Categorias: .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é +.

Adicione ao del.icio.us del.icio.us | Adicione ao Rec6 Rec6

7 comentários para “NHibernate: sugestão de arquitetura para uma aplicação CRUD”

  1. João Guilherme Pugsleyem 02 Jun 2007 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. Marcos Dell Antonioem 02 Jun 2007 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. Douglasem 13 Jun 2007 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. Marcos Dell Antonioem 13 Jun 2007 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. Joao Batistaem 10 Sep 2007 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. Marcos Dell Antonioem 15 Sep 2007 1:24 am

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

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

    T+

  7. Leandroem 20 Nov 2007 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?

Faça um comentário