terça-feira, 1 de novembro de 2011

Repository Pattern

Utilizando o padrão repositório, as telas e páginas da aplicação que fazem acessos a banco de dados passam a acessar classes intermediárias que atuam como repositórios de dados, tornando a aplicação independente de um banco de dados real. Dessa forma, há uma melhor separação de responsabilidades, onde as telas não possuem lógica de persistência, que passa a ser de responsabilidade do repositório. Isso facilita a troca de banco de dados (utilizar SQL Server, Oracle, MySQL, etc) e também os testes, uma vez que podemos criar repositórios “fake”, trabalhando com listas em memória, além de separar lógica de persistência da lógica de interface com o usuário.

Unit Of Work Pattern

Recentemente refatorei a minha versão de repositório que utilizo em minhas aplicações para dar suporte ao padrão UnitOfWork. Utilizando esse padrão, os repositórios passam a compartilhar entre si um objeto que faz a coordenação das transações dos repositórios a ele anexados em uma única operação Commit/Rollback. Ou seja, ao instanciar os repositórios para uma determinada operação, devo instanciar antes um objeto que implementa IUnitOfWork, e passá-lo na construção desses repositórios. Ao chamar o método Commit() do UnitOfWork, todos os repositórios anexados serão persistidos.


Como foi implementado o repositório?

Após uma refatoração completa, a interface do repositório agora depende de uma interface IUnitOfWork:



Com essa interface criada, podemos criar agora a interface IRepositorio:




Uma classe de extensão para alguns métodos úteis aos repositórios que forem implementados:


Temos o repositório, agora falta a implementação da interface UnitOfWork. Para implementar esta interface, achei conveniente criar uma classe base:

Precisamos da classe Container para nos auxiliar nas implementações de UnitOfWork:



Em seguida todas as implementações para os diversos bancos de dados que desejarmos devem herdar desta classe base, implementando a interface. A seguir a implementação padrão que utiliza Entity Framework CodeFirst, onde no construtor passa-se o DbContext.

A seguir a implementação padrão que utiliza Entity Framework tradicional, onde no construtor passa-se o ObjectContext.



Solução

Download da solution Abaixo segue o código demonstrando como utilizar o Entity Framework 4.1 Code First com 2 tabelas (Pessoas e Enderecos), com relacionamento Many-to-Many, e abstraindo o EFramework com o padrão repositório da forma mais simples, sem injeção de dependência.

Mostre código! 

Classe Pessoa


Classe Endereco


Classe de Mapeamento e Configuração do Entity Framework


Método de teste

Um comentário:

  1. Jone sua classe contempla consulta com uso do Include? Por exemplo:

    Dim x = (From a In New Context().CLIENTES.Include("PEDIDOS") Where a.ID = 1).FirstOrDefault

    ResponderExcluir