Repository Pattern: Guia Essencial de Acesso a Dados

O Repository Pattern é uma forma de organizar o acesso a dados, criando uma camada que esconde toda a lógica de persistência (leitura e escrita no banco de dados, por exemplo) atrás de métodos mais amigáveis. Dessa forma, a aplicação “conversa” com essa camada intermediária em vez de lidar diretamente com consultas🎲 Desafio: Analise Dados de Vendas com LINQ e Coleções!🎲 Desafio: Analise Dados de Vendas com LINQ e Coleções!Aprenda a usar coleções e LINQ em C# para analisar vendas, filtrar dados e extrair insights estratégicos que otimizem decisões e impulsionem seu negócio. SQL ou chamadas a um ORM. A ideia é facilitar manutenções, testes e trocas de fontes de dados, promovendo um código mais limpo e flexível. Imagine que você está construindo um prédio, mas cada pedreiro decide onde colocar as vigas, portas e janelas. O caos seria inevitável, certo? O Repository Pattern é o arquiteto que organiza o acesso aos dados na sua aplicação. Vamos desvendar como ele funciona na prática!

Sumário🔗

🧱 O que é o Repository Pattern?🔗

O Repository Pattern propõe a criação de uma camada especial para lidar com a persistência de dados, representada pelos “repositórios🤝 GitHub Básico: Versionamento para Iniciantes!🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes.”. Em vez de o seu código de negócio fazer consultas diretas no banco de dados, ele pede para o repositório fazer esse trabalho. Assim, a camada de negócio (ou de aplicação) fica independente dos detalhes específicos de como os dados são armazenados.

Imagine que você precisa salvar e recuperar informações de produtos de um banco SQL hoje, mas amanhã decide usar um serviço de storage na nuvem. Se todo o acesso aos dados estiver centralizado no repositório🤝 GitHub Básico: Versionamento para Iniciantes!🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes., basta trocar a implementação por outra que saiba falar com a nuvem, mantendo a interface de uso inalterada no restante do sistema.

Funciona como um "garçom" que:

Sem Repository:

// Controller diretamente acessando EF Core
public class ClienteController : Controller
{
    private readonly AppDbContext _context;
    public IActionResult GetClientes()
    {
        return Ok(_context.Clientes.Where(c => c.Ativo).ToList());
    }
}

Com Repository:

public class ClienteController : Controller
{
    private readonly IClienteRepository _repo;
    public IActionResult GetClientes()
    {
        return Ok(_repo.GetAtivos());
    }
}

🚀 Vantagens e Quando Usar🔗

Vantagens

Quando📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. Usar

VantagemExemplo Prático
Troca de TecnologiaMigrar de SQL Server para Cosmos DB
TestabilidadeMockar repositórios em testes
ManutençãoCentralizar regras de acesso
Clean ArchitectureSeparar camadas claramente

Criando a Interface do Repositório🔗

Uma interface de repositório geralmente segue a ideia de CRUD (Create, Read, Update, Delete), mas pode ser adaptada às necessidades do projeto. Exemplo de interface para repositório🤝 GitHub Básico: Versionamento para Iniciantes!🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes. de produtos:

public interface IProdutoRepository
{
    void Add(Produto produto);
    Produto? GetById(int id);
    IEnumerable<Produto> GetAll();
    void Update(Produto produto);
    void Delete(int id);
}

Note que aqui não estamos preocupados se é um banco SQL, NoSQL ou qualquer outro. Como consumidor dessa interface📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!Descubra como as interfaces em C# funcionam como contratos que garantem implementações flexíveis e robustas, facilitando o design e testes de sistemas., basta chamar os métodos, sem saber como os dados são efetivamente armazenados.

Implementação em C#: Exemplo Prático🔗

Abaixo segue um exemplo simples usando Entity Framework🌍 Projeto: API de E-Commerce com ASP.NET Core e SQL Server!🌍 Projeto: API de E-Commerce com ASP.NET Core e SQL Server!Aprenda a construir uma API robusta para e-commerce com ASP.NET Core, EF Core, JWT e Swagger, validando suas habilidades em um projeto prático real. (apenas como ilustração do que um repositório poderia fazer “por baixo dos panos”):

public class ProdutoRepository : IProdutoRepository
{
    private readonly AppDbContext _context;
    public ProdutoRepository(AppDbContext context)
    {
        _context = context;
    }
    public void Add(Produto produto)
    {
        _context.Produtos.Add(produto);
        _context.SaveChanges();
    }
    public Produto? GetById(int id)
    {
        return _context.Produtos.Find(id);
    }
    public IEnumerable<Produto> GetAll()
    {
        return _context.Produtos.ToList();
    }
    public void Update(Produto produto)
    {
        _context.Produtos.Update(produto);
        _context.SaveChanges();
    }
    public void Delete(int id)
    {
        var produto = _context.Produtos.Find(id);
        if (produto != null)
        {
            _context.Produtos.Remove(produto);
            _context.SaveChanges();
        }
    }
}

Nesse caso, AppDbContext é a classe de contexto do Entity Framework🌍 Projeto: API de E-Commerce com ASP.NET Core e SQL Server!🌍 Projeto: API de E-Commerce com ASP.NET Core e SQL Server!Aprenda a construir uma API robusta para e-commerce com ASP.NET Core, EF Core, JWT e Swagger, validando suas habilidades em um projeto prático real., mas nada impede que essa implementação seja refeita para outro banco ou tecnologia. O restante do sistema não precisa saber disso, pois interage apenas com IProdutoRepository.

🏢 Exemplo Real: Sistema de CRM🔗

Repositório🤝 GitHub Básico: Versionamento para Iniciantes!🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes. Especializado:

public interface IClienteRepository : IRepository<Cliente>
{
    Task<IEnumerable<Cliente>> GetPremiumClientes();
    Task<Cliente> GetByEmail(string email);
}
public class ClienteRepository : Repository<Cliente>, IClienteRepository
{
    public ClienteRepository(AppDbContext context) : base(context) { }
    public async Task<IEnumerable<Cliente>> GetPremiumClientes()
    {
        return await _dbSet
            .Where(c => c.Plano == Plano.Premium && c.UltimaCompra > DateTime.Now.AddMonths(-1))
            .ToListAsync();
    }
}

Uso no Controller🛠️ Controllers: Rotas que Respondem como Mágica!🛠️ Controllers: Rotas que Respondem como Mágica!Aprenda a criar e configurar controllers no ASP.NET Core com dicas práticas, exemplos de rotas e integração de serviços, elevando a qualidade da sua API.:

[ApiController]
[Route("clientes")]
public class ClienteController : ControllerBase
{
    private readonly IClienteRepository _clientes;
    public ClienteController(IClienteRepository clientes)
    {
        _clientes = clientes;
    }
    [HttpGet("premium")]
    public async Task<IActionResult> GetPremium()
    {
        return Ok(await _clientes.GetPremiumClientes());
    }
}

🧠 Dicas Avançadas🔗

1. Unit of Work Pattern:

public interface IUnitOfWork
{
    IClienteRepository Clientes { get; }
    IPedidoRepository Pedidos { get; }
    Task CommitAsync();
}

2. CQRS + Repository:

Separe operações de leitura (IQuery) e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. escrita (ICommand🔍 Comandos: Desacople Ações dos Botões!🔍 Comandos: Desacople Ações dos Botões!Aprenda a implementar comandos em C# para desacoplar lógica e interface usando MVVM, com exemplos práticos e dicas para melhor testabilidade e manutenção.)

3. Testes com Moq🎭 Moq: Simule Dependências para Testes Isolados!🎭 Moq: Simule Dependências para Testes Isolados!Aprenda a dominar o Moq em C#: simule dependências e melhore seus testes unitários com exemplos práticos, dicas avançadas e estratégias para um código seguro.:

var mockRepo = new Mock<IClienteRepository>();
mockRepo.Setup(r => r.GetByIdAsync(1))
        .ReturnsAsync(new Cliente { Nome = "João" });

⚠️ Erros Comuns🔗

1. Repository God Object:

// ❌ Ruim
repo.GetClientesAtivosComPedidosAtrasadosEEndereco()
// ✅ Bom
clienteRepo.GetAtivos();
pedidoRepo.GetAtrasados(clienteId);

2. Ignorar Performance🔄 StringBuilder: Quando Concatenar Strings Vira um Pesadelo!🔄 StringBuilder: Quando Concatenar Strings Vira um Pesadelo!Descubra como o StringBuilder otimiza a concatenação em C#, evitando desperdício de memória e melhorando a performance das aplicações. Veja exemplos práticos!:

3. Acoplamento ao EF:

// ❌ Vazando detalhes do ORM
public interface IClienteRepository
{
    DbSet<Cliente> GetDbSet();
}

🏁 Conclusão🔗

O Repository Pattern é uma abordagem essencial para quem quer manter o código de acesso a dados bem estruturado, seguro contra mudanças de tecnologia e mais fácil de testar e manter. A ideia principal é criar uma camada transparente de comunicação com as fontes de dados, permitindo que o restante do sistema continue funcionando mesmo que a forma de persistência mude. Dessa maneira, seu projeto ganha organização e escalabilidade📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos., sem amarrar todas as partes do sistema a detalhes específicos de armazenamento de dados.

O Repository Pattern é como organizar sua geladeira:

Próximo passo? Combine com Unit of Work para🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! transações complexas! 🔥

Autor: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.

Referências🔗

Compartilhar artigo

Artigos Relacionados