Repository Pattern no .NET: um guia direto ao ponto
Sem enrolação: vamos falar do Repository Pattern como gente de verdade. Pense nele como um intermediário entre a sua lógica de negócio e o seu banco de dados, só que um intermediário que facilita a sua vida.
Por que você deveria se importar?
Imagina a situação: você está construindo uma aplicação e o código de banco de dados está em todo lugar. Amanhã, seu chefe diz "Vamos trocar o SQL Server por MongoDB." Você provavelmente ia querer chorar, né? É aí que o Repository Pattern te salva.
Em bom português: é uma camada que fica entre a sua aplicação e o banco de dados, para você poder trocar a fonte de dados sem reescrever metade do código.
Um exemplo do mundo real
Digamos que você está construindo um blog simples. Você precisa salvar e buscar posts. Veja como a maioria das pessoas começa:
// ❌ A abordagem "vou me arrepender depois"
public class BlogService
{
private readonly DbContext _db;
public BlogPost GetPost(int id)
{
return _db.BlogPosts.FirstOrDefault(p => p.Id == id);
}
}
Isso funciona, mas agora seu BlogService está casado com o Entity Framework. Boa sorte testando isso ou trocando de banco.
Entra o Repository Pattern
O jeito mais esperto é este:
Passo 1: defina o que você precisa (a interface)
public interface IBlogRepository
{
BlogPost GetById(int id);
IEnumerable<BlogPost> GetAll();
void Add(BlogPost post);
void Update(BlogPost post);
void Delete(int id);
}
Este é o seu contrato. Percebeu como ele não diz nada sobre banco de dados? Isso é proposital.
Passo 2: implemente (o repositório de verdade)
public class BlogRepository : IBlogRepository
{
private readonly ApplicationDbContext _context;
public BlogRepository(ApplicationDbContext context)
{
_context = context;
}
public BlogPost GetById(int id)
{
return _context.BlogPosts.FirstOrDefault(p => p.Id == id);
}
public IEnumerable<BlogPost> GetAll()
{
return _context.BlogPosts.ToList();
}
public void Add(BlogPost post)
{
_context.BlogPosts.Add(post);
_context.SaveChanges();
}
public void Update(BlogPost post)
{
_context.BlogPosts.Update(post);
_context.SaveChanges();
}
public void Delete(int id)
{
var post = GetById(id);
if (post != null)
{
_context.BlogPosts.Remove(post);
_context.SaveChanges();
}
}
}
Passo 3: use no seu service
public class BlogService
{
private readonly IBlogRepository _repository;
public BlogService(IBlogRepository repository)
{
_repository = repository;
}
public BlogPost GetPost(int id)
{
return _repository.GetById(id);
}
public void PublishPost(BlogPost post)
{
post.PublishedAt = DateTime.Now;
_repository.Add(post);
}
}
Passo 4: configure a injeção de dependência
No seu Program.cs:
builder.Services.AddScoped<IBlogRepository, BlogRepository>();
builder.Services.AddScoped<BlogService>();
O que acabou de acontecer?
Agora o seu BlogService não tem a menor ideia de que existe Entity Framework ou banco de dados. Ele só sabe que pode pedir posts e salvá-los.
Quer trocar para Dapper? MongoDB? Um arquivo JSON? Basta criar uma nova implementação de IBlogRepository. O código do seu service fica intocado.
Os benefícios na prática
- Testar fica moleza: você faz mock do
IBlogRepositorye testa a lógica de negócio sem encostar no banco. - Você ganha flexibilidade para trocar a fonte de dados sem reescrever a aplicação inteira.
- O código fica mais limpo, porque cada classe tem uma responsabilidade e faz isso bem.
- A equipe agradece: ninguém vai te odiar quando precisar dar manutenção nisso depois.
Quando não usar
Papo reto: se você está construindo uma aplicação CRUD pequena com 3 tabelas, isso pode ser exagero. Não faça over-engineering. Mas se sua aplicação está crescendo ou você sabe que vai crescer, o Repository Pattern é seu amigo.
Resumindo
O Repository Pattern é só organização bem feita. Você traça uma linha clara entre "como armazenamos os dados" e "o que fazemos com eles".
O seu eu do futuro (e os seus colegas) vão agradecer.
Tem dúvidas ou alguma história de guerra com o Repository Pattern? Quero ouvir. Me manda uma mensagem!
Este artigo foi revisado e aprimorado com o uso de IA.