DBContext
Consumindo o DbContext
O DbContext, por padrão, já encapsula o Repository Pattern.
O Entity Framework Core abstrai o acesso aos dados por meio do DbSet<T>, controle de estado de entidades e implementação do padrão Unit of Work, eliminando a necessidade de criação de repositórios manuais em cenários simples.
Neste fase do projeto, o DbContext será consumido diretamente pelos endpoints para fins didáticos, demonstrando sua funcionalidade básica.
Injeção do DbContext em Minimal APIs
O AppDbContext é previamente registrado no container de injeção de dependência:
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<AppDbContext>(options =>
{
options.UseSqlServer(connectionString);
});Com essa configuração, o contexto pode ser injetado diretamente nos handlers dos Minimal APIs. O runtime resolve automaticamente essa dependência para cada requisição, garantindo o isolamento apropriado do contexto.
Configuração de Rotas HTTP
No arquivo Program.cs, além do mapeamento do endpoint GET, são configuradas as rotas para POST, PUT e DELETE. As rotas permanecem consistentes (/v1/products), diferenciando-se apenas pelo verbo HTTP utilizado.
No Minimal API, a injeção do contexto aparece como parâmetro em uma função anônima:
O runtime reconhece automaticamente que o AppDbContext deve ser resolvido por injeção de dependência para cada requisição, utilizando o ciclo de vida scoped configurado.
Endpoint GET - Listagem de Produtos
Para recuperar todos os produtos, o método é tornado assíncrono e utilizado o método ToListAsync():
Componentes envolvidos:
Products: refere-se à propriedade DbSet<Product> definida no contexto
ToListAsync() executa a consulta de forma assíncrona, retornando todos os registros
O Entity Framework Core gerencia automaticamente a conexão, execução de comandos e mapeamento de resultados
Operações CRUD Básicas
O Entity Framework Core fornece métodos padrão para operações CRUD, pois implementa internamente o padrão Repository:
Criação: AddAsync()
Atualização: Update()
Remoção: Remove()
Esses métodos funcionam eficientemente porque o DbContext mantém o rastreamento do estado das entidades durante seu ciclo de vida, implementando o padrão Unit of Work.
Exemplo com Modelo Adicional (Category)
Não implementar esse exemplo.
Considerando a criação de um novo modelo Category no diretório Models:
É necessário registrar o DbSet correspondente no AppDbContext existente no diretório Data:
Com essa configuração, torna-se possível mapear um endpoint diretamente no Program.cs:
Essa abordagem demonstra-se funcional, simples e rápida de implementar.
Limitações da Abordagem Direta
No endpoint GET de produtos, seria possível aplicar otimizações diretamente:
Problemas Estruturais Identificados
Esta lógica direta apresenta limitações significativas:
Acoplamento excessivo: A lógica de acesso a dados fica diretamente vinculada à camada de apresentação
Reutilização impossibilitada: A implementação não pode ser compartilhada entre diferentes componentes do sistema
Exposição da infraestrutura: Detalhes internos da estrutura de persistência ficam expostos
Mistura de responsabilidades: Não há separação clara entre regras de negócio e lógica de apresentação
Dificuldade de teste: A lógica de dados acoplada aos endpoints dificulta testes unitários
Escalabilidade comprometida: Funciona adequadamente para projetos pequenos, mas não escala bem para sistemas maiores
A fronteira entre "dados" e "apresentação" torna-se difusa, comprometendo a manutenibilidade e evolução do sistema.
Decisão arquitetural
A partir deste momento, o acesso ao banco de dados não será mais realizado diretamente no Program.cs. Esta abordagem inicial, embora didática, é substituída por uma estrutura mais robusta.
Próximo Passo: Implementação de Repositórios
A partir deste momento, será realizada a implementação dos Repositórios, encapsulando:
Queries complexas: Centralização de consultas específicas do domínio
Regras de acesso: Controle de permissões e lógica de acesso a dados
Reutilização de código: Compartilhamento de lógica entre diferentes partes do sistema
Controle de complexidade: Isolamento da complexidade de acesso a dados
Abstração de infraestrutura: Separação entre lógica de negócio e detalhes de persistência
A Minimal API continua sendo utilizada, e o DbContext permanece como componente fundamental. Contudo, não será mais exposto diretamente na camada de apresentação.
Agora inicia-se verdadeiramente a arquitetura de software, com a implementação dos repositórios estabelecendo uma clara separação de responsabilidades e preparando o sistema para escalabilidade e manutenibilidade de longo prazo.
Atualizado