Top 25 perguntas de entrevista de ASP.NET Core: middleware, DI e minimal APIs
As perguntas de entrevista de ASP.NET Core mais comuns sobre o pipeline de middleware, os tempos de vida da injeção de dependências e as minimal APIs. Cobre as novidades do .NET 9 e do .NET 10 com exemplos de código.

As perguntas de entrevista de ASP.NET Core sobre middleware, injeção de dependências e minimal APIs continuam entre os tópicos mais frequentes nas entrevistas técnicas de .NET. Seja para uma vaga voltada ao desenvolvimento backend ou a posições full-stack .NET, os entrevistadores sondam de forma consistente a compreensão do pipeline de requisições, dos tempos de vida dos serviços e do modelo de API enxuto introduzido no .NET 6 e refinado até o .NET 10.
A ordem do pipeline de middleware, as incompatibilidades de tempo de vida na DI (o problema da dependência cativa) e a capacidade de articular os prós e contras entre minimal APIs e controllers. Essas três áreas representam a maioria das perguntas de entrevista de ASP.NET Core nos níveis pleno e sênior.
Perguntas sobre o pipeline de middleware do ASP.NET Core
1. O que é middleware no ASP.NET Core?
O middleware é um componente montado no pipeline da aplicação para tratar requisições e respostas. Cada componente de middleware decide se passa a requisição para o próximo componente ou se interrompe o pipeline. O middleware é executado na ordem em que é registrado no Program.cs, e a resposta retorna pelos mesmos componentes na ordem inversa.
2. Como funciona a ordem de execução do middleware?
A ordem das chamadas app.Use*() no Program.cs define a sequência de execução exata. Uma requisição flui de cima para baixo por cada middleware, e a resposta flui de baixo para cima. É por isso que UseAuthentication() deve aparecer antes de UseAuthorization(), e UseRouting() antes de UseEndpoints().
var app = builder.Build();
app.UseExceptionHandler("/error"); // 1. Outermost: catches all exceptions
app.UseHsts(); // 2. HTTP Strict Transport Security
app.UseHttpsRedirection(); // 3. Redirect HTTP to HTTPS
app.UseStaticFiles(); // 4. Serve static files (short-circuits if found)
app.UseRouting(); // 5. Match request to endpoint
app.UseAuthentication(); // 6. Identify the user
app.UseAuthorization(); // 7. Check permissions
app.MapControllers(); // 8. Execute the matched endpoint
app.Run();Colocar UseStaticFiles() antes da autenticação evita verificações de autorização desnecessárias nas requisições de CSS, JS e imagens. Essa é uma pergunta de acompanhamento frequente em entrevistas.
3. Como escrever um middleware personalizado?
Um middleware personalizado pode ser implementado como uma classe com um método InvokeAsync ou inline com app.Use(). A abordagem baseada em classe é preferível para código de produção porque oferece suporte à injeção de dependências por meio dos parâmetros do construtor.
public class RequestTimingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RequestTimingMiddleware> _logger;
public RequestTimingMiddleware(RequestDelegate next, ILogger<RequestTimingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
var stopwatch = Stopwatch.StartNew();
await _next(context); // Call the next middleware
stopwatch.Stop();
_logger.LogInformation(
"Request {Method} {Path} completed in {Elapsed}ms",
context.Request.Method,
context.Request.Path,
stopwatch.ElapsedMilliseconds);
}
}
// Registration in Program.cs
app.UseMiddleware<RequestTimingMiddleware>();Vale destacar que as classes de middleware são instanciadas uma única vez (tempo de vida singleton), enquanto InvokeAsync é chamado a cada requisição. Essa distinção é importante para a segurança de threads.
4. Qual é a diferença entre app.Use(), app.Run() e app.Map()?
app.Use() adiciona um middleware que chama o próximo delegate. app.Run() é um middleware terminal que não chama o próximo, encerrando o pipeline. app.Map() ramifica o pipeline com base no caminho da requisição. Um erro comum é colocar app.Run() cedo demais, o que interrompe todo o middleware subsequente.
5. Como funciona o curto-circuito do middleware?
Qualquer middleware pode interromper o pipeline ao não chamar next(). É assim que UseStaticFiles() funciona: se um arquivo estático corresponde ao caminho da requisição, ele o retorna diretamente sem invocar o middleware de autenticação, autorização ou roteamento. O middleware de limitação de taxa também usa o curto-circuito para retornar respostas 429 antes de chegar ao endpoint.
6. O que mudou no middleware com o .NET 9?
O .NET 9 estendeu o suporte de injeção de dependências por chave ao middleware. O atributo [FromKeyedServices] agora funciona tanto no construtor do middleware (para serviços singleton/transient) quanto no método InvokeAsync (para todos os tempos de vida, incluindo scoped). Isso elimina a necessidade de soluções do tipo service locator quando um middleware precisa de implementações diferentes da mesma interface.
Perguntas de entrevista sobre injeção de dependências
7. Quais são os três tempos de vida de serviço na DI?
O ASP.NET Core oferece três tempos de vida: Transient (uma nova instância a cada vez), Scoped (uma instância por requisição HTTP) e Singleton (uma instância durante toda a vida da aplicação). Essa escolha afeta diretamente o uso de memória, a segurança de threads e o compartilhamento de estado entre componentes.
Injetar um serviço scoped em um singleton cria uma dependência cativa: o serviço scoped vive tanto quanto o singleton e compartilha seu estado entre requisições. Habilite ValidateScopes em desenvolvimento para detectar isso na inicialização.
8. Explique o problema da dependência cativa com um exemplo
Quando um serviço singleton recebe uma dependência scoped por meio de seu construtor, essa instância scoped nunca é liberada entre requisições. Ela se torna "cativa" dentro do tempo de vida do singleton. Isso leva ao compartilhamento de estado entre requisições HTTP, o que pode causar vazamentos de dados e condições de corrida.
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddSingleton<ICacheService, CacheService>(); // CacheService takes IUserRepository
// This throws at startup in Development when ValidateScopes is enabled:
builder.Host.UseDefaultServiceProvider(options =>
{
options.ValidateScopes = true; // Catches captive dependencies
options.ValidateOnBuild = true; // Validates all registrations at startup
});A solução: injetar IServiceScopeFactory no singleton e criar um scope manualmente quando o serviço scoped for necessário.
9. O que são serviços por chave (keyed services) e quando usá-los?
Os serviços por chave, introduzidos no .NET 8, permitem registrar várias implementações da mesma interface com chaves diferentes. Isso elimina os padrões de factory personalizados e a lógica de resolução condicional complexa.
builder.Services.AddKeyedSingleton<INotificationService, EmailNotification>("email");
builder.Services.AddKeyedSingleton<INotificationService, SmsNotification>("sms");
builder.Services.AddKeyedSingleton<INotificationService, PushNotification>("push");
// Resolving in a controller or service
public class OrderService
{
public OrderService(
[FromKeyedServices("email")] INotificationService emailService,
[FromKeyedServices("sms")] INotificationService smsService)
{
// Each parameter gets its specific implementation
}
}Antes dos serviços por chave, isso exigia uma classe factory, registros nomeados com contêineres de terceiros ou resolução manual a partir de IServiceProvider.
10. Ainda vale a pena usar contêineres DI de terceiros com o ASP.NET Core?
O contêiner integrado cobre a maioria dos cenários a partir do .NET 9/10: injeção por construtor, serviços por chave, genéricos abertos e padrões de decorator (via registro manual). Contêineres de terceiros como Autofac ou Lamar continuam úteis para cenários avançados como injeção por propriedade, interceptação/AOP, registro por módulos ou escaneamento por convenção em grandes assemblies. Para a maioria das aplicações, o contêiner integrado é suficiente.
11. Como a DI funciona nas minimal APIs em comparação com os controllers?
Os controllers recebem suas dependências por injeção de construtor. Os endpoints de minimal API as recebem como parâmetros de método, resolvidos automaticamente a partir do contêiner DI. Tipos especiais como HttpContext, CancellationToken e ClaimsPrincipal também são vinculados automaticamente sem registro explícito.
12. O que é o padrão Options?
O padrão Options vincula seções de configuração a classes fortemente tipadas. Ele separa a configuração da lógica do serviço e oferece suporte a validação, opções nomeadas e recarga em tempo de execução via IOptionsMonitor<T>. Injetar diretamente IConfiguration nos serviços é um antipadrão porque acopla fortemente os serviços à estrutura de configuração.
Pronto para mandar bem nas entrevistas de .NET?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Perguntas de entrevista sobre minimal APIs
13. O que são minimal APIs e como elas diferem dos controllers?
As minimal APIs, introduzidas no .NET 6, definem os endpoints HTTP diretamente no Program.cs usando app.MapGet(), app.MapPost() e métodos semelhantes. Elas eliminam a necessidade de classes controller, atributos de model binding e filtros de ação. Os controllers oferecem suporte integrado a filtros, validação de modelo e negociação de conteúdo. As minimal APIs são mais enxutas, mas exigem configuração manual para preocupações transversais.
14. Quando escolher minimal APIs em vez de controllers?
As minimal APIs são adequadas para microsserviços, APIs leves e cenários em que o desempenho de inicialização importa. Os controllers se encaixam em aplicações grandes com pipelines de filtragem complexos, model binding extenso ou equipes acostumadas às convenções do MVC. Ambos podem coexistir na mesma aplicação.
15. Como estruturar minimal APIs em um projeto real?
Evite colocar todos os endpoints no Program.cs. Use métodos de extensão para organizar os endpoints por funcionalidade ou domínio, mantendo os manipuladores de rota enxutos e delegando a lógica de negócio aos serviços.
public static class ProductEndpoints
{
public static void MapProductEndpoints(this WebApplication app)
{
var group = app.MapGroup("/api/products")
.WithTags("Products")
.RequireAuthorization();
group.MapGet("/", GetAll);
group.MapGet("/{id:int}", GetById);
group.MapPost("/", Create);
}
private static async Task<IResult> GetAll(
IProductService productService, // Auto-resolved from DI
CancellationToken cancellationToken)
{
var products = await productService.GetAllAsync(cancellationToken);
return TypedResults.Ok(products);
}
private static async Task<IResult> GetById(
int id,
IProductService productService)
{
var product = await productService.GetByIdAsync(id);
return product is null
? TypedResults.NotFound()
: TypedResults.Ok(product);
}
private static async Task<IResult> Create(
CreateProductRequest request,
IProductService productService)
{
var product = await productService.CreateAsync(request);
return TypedResults.Created($"/api/products/{product.Id}", product);
}
}
// Program.cs — Clean registration
app.MapProductEndpoints();Esse padrão escala bem: cada pasta de funcionalidade contém seus endpoints, seus DTOs e suas interfaces de serviço.
16. Como funciona a validação nas minimal APIs?
O .NET 10 introduziu a validação integrada para minimal APIs. Antes do .NET 10, a validação exigia implementação manual ou bibliotecas de terceiros como o FluentValidation. Com o .NET 10, as anotações de dados nos tipos de parâmetros são validadas automaticamente, e as requisições inválidas retornam uma resposta 400 com problem details.
17. O que é TypedResults e por que usá-lo?
TypedResults (introduzido no .NET 7) oferece segurança de tipos em tempo de compilação para as respostas da API e habilita a geração automática de documentação OpenAPI. Diferente de Results, que retorna IResult, os métodos de TypedResults retornam tipos específicos como Ok<T> ou NotFound, permitindo ao framework gerar esquemas de resposta precisos.
18. Como tratar Server-Sent Events em minimal APIs?
O .NET 10 adicionou TypedResults.ServerSentEvents() para respostas em streaming. Isso elimina a escrita manual em Response.Body e trata automaticamente a serialização JSON, os cabeçalhos content-type e o gerenciamento da conexão.
Perguntas de entrevista avançadas
19. Como o pipeline de requisições interage com o roteamento de endpoints?
UseRouting() corresponde a requisição recebida a um endpoint, mas não o executa. O middleware situado entre UseRouting() e MapControllers()/MapEndpoints() pode inspecionar os metadados do endpoint correspondente (por exemplo, os atributos de autorização) antes da execução. É assim que UseAuthorization() lê os atributos [Authorize] definidos em controllers ou endpoints de minimal API.
20. Qual é a diferença entre AddTransient, AddScoped e AddSingleton para IHttpClientFactory?
Nunca registre HttpClient como singleton: ele ignora mudanças de DNS e esgota as conexões de socket. IHttpClientFactory (via AddHttpClient()) gerencia corretamente os tempos de vida de HttpClient: as instâncias de HttpClient são transient, mas o pool subjacente de HttpMessageHandler é gerenciado com um tempo de vida configurável (2 minutos por padrão). Isso evita o esgotamento de sockets ao mesmo tempo que respeita os TTLs de DNS.
21. Como implementar o padrão decorator com a DI integrada?
O contêiner integrado não oferece suporte nativo a decorators, mas isso pode ser alcançado manualmente usando delegates de factory.
// Decorating IProductService with caching
builder.Services.AddScoped<ProductService>();
builder.Services.AddScoped<IProductService>(sp =>
{
var inner = sp.GetRequiredService<ProductService>();
var cache = sp.GetRequiredService<IMemoryCache>();
return new CachedProductService(inner, cache);
});Para aplicações que exigem muitos decorators, um contêiner de terceiros como o Scrutor oferece uma API Decorate<TInterface, TDecorator>() mais limpa.
22. Como o middleware difere dos endpoint filters nas minimal APIs?
O middleware é executado para cada requisição do pipeline, independentemente do endpoint. Os endpoint filters (introduzidos no .NET 7) são executados apenas para os endpoints correspondentes, de forma semelhante aos filtros de ação no MVC. Os filtros têm acesso ao contexto específico do endpoint e são registrados por rota ou por grupo. Use middleware para preocupações transversais como logging e CORS; use filtros para lógica específica do endpoint como validação ou transformação.
23. O que é HybridCache no .NET 9?
O HybridCache combina o cache em memória (L1) e distribuído (L2) por trás de uma única API. Ele trata automaticamente a proteção contra cache stampede: quando várias requisições concorrentes falham no cache para a mesma chave, apenas uma executa o método factory enquanto as demais aguardam. Isso substitui a coordenação manual entre IMemoryCache e IDistributedCache, que antes era propensa a erros.
24. Como testar o middleware de forma isolada?
O middleware pode ser testado usando DefaultHttpContext e um RequestDelegate personalizado. Crie uma instância do middleware, passe um contexto simulado e verifique as propriedades da resposta.
[Fact]
public async Task Middleware_LogsElapsedTime()
{
var logger = new FakeLogger<RequestTimingMiddleware>();
var middleware = new RequestTimingMiddleware(
next: (ctx) => Task.CompletedTask, // Terminal delegate
logger: logger);
var context = new DefaultHttpContext();
context.Request.Method = "GET";
context.Request.Path = "/api/products";
await middleware.InvokeAsync(context);
Assert.Single(logger.LogEntries);
Assert.Contains("completed in", logger.LogEntries[0].Message);
}Para testes de integração, WebApplicationFactory<T> oferece um teste completo do pipeline que inclui a ordem do middleware.
25. Quais são as mudanças de OpenAPI no .NET 9 e no .NET 10?
O .NET 9 substituiu o Swagger/Swashbuckle pela geração integrada de documentos OpenAPI via Microsoft.AspNetCore.OpenApi. O .NET 10 atualizou para a biblioteca OpenAPI v2.0 com suporte a YAML, esquemas de tipos nullable aprimorados (usando oneOf em vez da propriedade nullable) e melhor integração dos comentários de documentação XML. Os documentos gerados são servidos em /openapi/v1.json por padrão. Scalar ou Swagger UI podem ser adicionados como um pacote separado para documentação interativa.
Pratique explicar o pipeline de middleware em um quadro branco: desenhe a requisição descendo por cada middleware e a resposta subindo de volta. Entrevistadores de empresas como Microsoft, Accenture e consultorias usam com frequência esse exercício para avaliar a profundidade da compreensão.
Conclusão
- A ordem de execução do middleware é determinística e crítica para a segurança: tratamento de exceções primeiro, arquivos estáticos antes da autenticação, roteamento antes da autorização
- O problema da dependência cativa (scoped dentro de um singleton) é o bug de DI mais comum; habilite
ValidateScopeseValidateOnBuildem desenvolvimento - Os serviços por chave do .NET 8/9 eliminam a maior parte da necessidade de contêineres DI de terceiros ou padrões de factory personalizados
- As minimal APIs e os controllers coexistem; escolha de acordo com a complexidade do projeto, as convenções da equipe e os requisitos de filtragem
- Estruture as minimal APIs usando métodos de extensão e grupos de rotas para manter o
Program.cslimpo - O .NET 10 adiciona validação integrada de minimal APIs, suporte a SSE via TypedResults e geração de OpenAPI aprimorada
- Teste o middleware de forma isolada com
DefaultHttpContext; useWebApplicationFactorypara testes de integração
Pratique essas perguntas com código real no simulador de entrevistas .NET da SharpSkill, que cobre os módulos de minimal APIs, desenvolvimento de Web API e clean architecture.
Comece a praticar!
Teste seus conhecimentos com nossos simuladores de entrevista e testes tecnicos.
Tags
Compartilhar
Artigos relacionados

Perguntas de Entrevista C# e .NET: Guia Completo 2026
As 25 perguntas mais comuns em entrevistas de C# e .NET. LINQ, async/await, injeção de dependência, Entity Framework e boas práticas com respostas detalhadas.

.NET MAUI em 2026: Desenvolvimento Multiplataforma e Perguntas de Entrevista
Tutorial de .NET MAUI para 2026: construir aplicativos multiplataforma com .NET 10, handlers, MVVM, HybridWebView. Inclui perguntas de entrevista com respostas detalhadas.

.NET 9 Blazor: Desenvolvimento Full-Stack com Blazor United em 2026
.NET 9 Blazor United combina renderização estática SSR, Server e WebAssembly em um framework full-stack unificado. Tutorial prático cobrindo modos de renderização, streaming, injeção por construtor e padrões prontos para produção.