Top 25 preguntas de entrevista de ASP.NET Core: middleware, DI y minimal APIs
Las preguntas de entrevista de ASP.NET Core más comunes sobre el pipeline de middleware, los tiempos de vida de la inyección de dependencias y las minimal APIs. Cubre las novedades de .NET 9 y .NET 10 con ejemplos de código.

Las preguntas de entrevista de ASP.NET Core sobre middleware, inyección de dependencias y minimal APIs siguen siendo de los temas más frecuentes en las entrevistas técnicas de .NET. Ya sea que el puesto apunte al desarrollo backend o a posiciones full-stack .NET, los entrevistadores indagan de forma constante sobre la comprensión del pipeline de solicitudes, los tiempos de vida de los servicios y el modelo de API ligero introducido en .NET 6 y refinado hasta .NET 10.
El orden del pipeline de middleware, las incompatibilidades de tiempo de vida en DI (el problema de la dependencia cautiva) y la capacidad de explicar las ventajas y desventajas entre minimal APIs y controladores. Estas tres áreas representan la mayoría de las preguntas de entrevista de ASP.NET Core en niveles intermedio y senior.
Preguntas sobre el pipeline de middleware de ASP.NET Core
1. ¿Qué es el middleware en ASP.NET Core?
El middleware es un componente ensamblado en el pipeline de la aplicación para manejar solicitudes y respuestas. Cada componente de middleware decide si pasa la solicitud al siguiente componente o cortocircuita el pipeline. El middleware se ejecuta en el orden en que se registra en Program.cs, y la respuesta regresa a través de los mismos componentes en orden inverso.
2. ¿Cómo funciona el orden de ejecución del middleware?
El orden de las llamadas app.Use*() en Program.cs define la secuencia de ejecución exacta. Una solicitud fluye de arriba hacia abajo a través de cada middleware, y la respuesta fluye de abajo hacia arriba. Por eso UseAuthentication() debe aparecer antes que UseAuthorization(), y UseRouting() antes que 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 de la autenticación evita verificaciones de autorización innecesarias en las solicitudes de CSS, JS e imágenes. Esta es una pregunta de seguimiento frecuente en entrevistas.
3. ¿Cómo escribir middleware personalizado?
El middleware personalizado puede implementarse como una clase con un método InvokeAsync o en línea con app.Use(). El enfoque basado en clases es preferible para el código de producción porque admite la inyección de dependencias a través de los parámetros del constructor.
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>();Cabe destacar que las clases de middleware se instancian una sola vez (tiempo de vida singleton) mientras que InvokeAsync se llama por cada solicitud. Esta distinción es importante para la seguridad de los hilos.
4. ¿Cuál es la diferencia entre app.Use(), app.Run() y app.Map()?
app.Use() agrega middleware que llama al siguiente delegado. app.Run() es un middleware terminal que no llama al siguiente, lo que finaliza el pipeline. app.Map() ramifica el pipeline según la ruta de la solicitud. Un error común es colocar app.Run() demasiado pronto, lo que cortocircuita todo el middleware posterior.
5. ¿Cómo funciona el cortocircuito del middleware?
Cualquier middleware puede cortocircuitar el pipeline al no llamar a next(). Así es como funciona UseStaticFiles(): si un archivo estático coincide con la ruta de la solicitud, lo devuelve directamente sin invocar el middleware de autenticación, autorización o enrutamiento. El middleware de limitación de tasa también usa el cortocircuito para devolver respuestas 429 antes de llegar al endpoint.
6. ¿Qué cambió en el middleware con .NET 9?
.NET 9 extendió el soporte de inyección de dependencias con clave al middleware. El atributo [FromKeyedServices] ahora funciona tanto en el constructor del middleware (para servicios singleton/transient) como en el método InvokeAsync (para todos los tiempos de vida, incluido scoped). Esto elimina la necesidad de soluciones tipo service locator cuando un middleware necesita diferentes implementaciones de la misma interfaz.
Preguntas de entrevista sobre inyección de dependencias
7. ¿Cuáles son los tres tiempos de vida de servicio en DI?
ASP.NET Core ofrece tres tiempos de vida: Transient (una nueva instancia cada vez), Scoped (una instancia por solicitud HTTP) y Singleton (una instancia durante toda la vida de la aplicación). Esta elección afecta directamente el uso de memoria, la seguridad de los hilos y el intercambio de estado entre componentes.
Inyectar un servicio scoped en un singleton crea una dependencia cautiva: el servicio scoped vive tanto como el singleton y comparte su estado entre solicitudes. Habilita ValidateScopes en desarrollo para detectar esto al inicio.
8. Explica el problema de la dependencia cautiva con un ejemplo
Cuando un servicio singleton recibe una dependencia scoped a través de su constructor, esa instancia scoped nunca se libera entre solicitudes. Queda "cautiva" dentro del tiempo de vida del singleton. Esto lleva a compartir estado entre solicitudes HTTP, lo que puede provocar fugas de datos y condiciones de carrera.
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
});La solución: inyectar IServiceScopeFactory en el singleton y crear un scope manualmente cuando se necesite el servicio scoped.
9. ¿Qué son los servicios con clave (keyed services) y cuándo usarlos?
Los servicios con clave, introducidos en .NET 8, permiten registrar múltiples implementaciones de la misma interfaz con diferentes claves. Esto elimina los patrones de factory personalizados y la lógica de resolución condicional compleja.
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 de los servicios con clave, esto requería una clase factory, registros con nombre con contenedores de terceros o resolución manual desde IServiceProvider.
10. ¿Conviene seguir usando contenedores DI de terceros con ASP.NET Core?
El contenedor integrado cubre la mayoría de los escenarios a partir de .NET 9/10: inyección por constructor, servicios con clave, genéricos abiertos y patrones de decorador (mediante registro manual). Los contenedores de terceros como Autofac o Lamar siguen siendo útiles para escenarios avanzados como la inyección por propiedad, la interceptación/AOP, el registro por módulos o el escaneo por convención en ensamblados grandes. Para la mayoría de las aplicaciones, el contenedor integrado es suficiente.
11. ¿Cómo funciona la DI en las minimal APIs frente a los controladores?
Los controladores reciben sus dependencias por inyección de constructor. Los endpoints de minimal API las reciben como parámetros de método, resueltos automáticamente desde el contenedor DI. Tipos especiales como HttpContext, CancellationToken y ClaimsPrincipal también se vinculan automáticamente sin registro explícito.
12. ¿Qué es el patrón Options?
El patrón Options vincula secciones de configuración a clases fuertemente tipadas. Separa la configuración de la lógica del servicio y admite validación, opciones con nombre y recarga en tiempo de ejecución mediante IOptionsMonitor<T>. Inyectar directamente IConfiguration en los servicios es un antipatrón porque acopla estrechamente los servicios a la estructura de la configuración.
¿Listo para aprobar tus entrevistas de .NET?
Practica con nuestros simuladores interactivos, flashcards y tests técnicos.
Preguntas de entrevista sobre minimal APIs
13. ¿Qué son las minimal APIs y en qué se diferencian de los controladores?
Las minimal APIs, introducidas en .NET 6, definen los endpoints HTTP directamente en Program.cs usando app.MapGet(), app.MapPost() y métodos similares. Eliminan la necesidad de clases controladoras, atributos de model binding y filtros de acción. Los controladores ofrecen soporte integrado para filtros, validación de modelo y negociación de contenido. Las minimal APIs son más ligeras pero requieren configuración manual para las preocupaciones transversales.
14. ¿Cuándo elegir minimal APIs en lugar de controladores?
Las minimal APIs son adecuadas para microservicios, APIs ligeras y escenarios donde el rendimiento de arranque importa. Los controladores encajan en aplicaciones grandes con pipelines de filtrado complejos, model binding extenso o equipos acostumbrados a las convenciones de MVC. Ambos pueden coexistir en la misma aplicación.
15. ¿Cómo estructurar minimal APIs en un proyecto real?
Evita colocar todos los endpoints en Program.cs. Usa métodos de extensión para organizar los endpoints por característica o dominio, manteniendo los manejadores de ruta ligeros y delegando la lógica de negocio a los servicios.
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();Este patrón escala bien: cada carpeta de característica contiene sus endpoints, sus DTO y sus interfaces de servicio.
16. ¿Cómo funciona la validación en las minimal APIs?
.NET 10 introdujo la validación integrada para minimal APIs. Antes de .NET 10, la validación requería implementación manual o bibliotecas de terceros como FluentValidation. Con .NET 10, las anotaciones de datos en los tipos de parámetros se validan automáticamente, y las solicitudes inválidas devuelven una respuesta 400 con problem details.
17. ¿Qué es TypedResults y por qué usarlo?
TypedResults (introducido en .NET 7) ofrece seguridad de tipos en tiempo de compilación para las respuestas de la API y habilita la generación automática de documentación OpenAPI. A diferencia de Results, que devuelve IResult, los métodos de TypedResults devuelven tipos específicos como Ok<T> o NotFound, lo que permite al framework generar esquemas de respuesta precisos.
18. ¿Cómo manejar Server-Sent Events en minimal APIs?
.NET 10 agregó TypedResults.ServerSentEvents() para respuestas en streaming. Esto elimina la escritura manual en Response.Body y maneja automáticamente la serialización JSON, los encabezados content-type y la gestión de la conexión.
Preguntas de entrevista avanzadas
19. ¿Cómo interactúa el pipeline de solicitudes con el enrutamiento de endpoints?
UseRouting() empareja la solicitud entrante con un endpoint pero no lo ejecuta. El middleware ubicado entre UseRouting() y MapControllers()/MapEndpoints() puede inspeccionar los metadatos del endpoint coincidente (por ejemplo, los atributos de autorización) antes de la ejecución. Así es como UseAuthorization() lee los atributos [Authorize] definidos en controladores o endpoints de minimal API.
20. ¿Cuál es la diferencia entre AddTransient, AddScoped y AddSingleton para IHttpClientFactory?
Nunca registres HttpClient como singleton: ignora los cambios de DNS y agota las conexiones de socket. IHttpClientFactory (mediante AddHttpClient()) gestiona correctamente los tiempos de vida de HttpClient: las instancias de HttpClient son transient, pero el pool subyacente de HttpMessageHandler se gestiona con un tiempo de vida configurable (2 minutos por defecto). Esto evita el agotamiento de sockets al tiempo que respeta los TTL de DNS.
21. ¿Cómo implementar el patrón decorador con la DI integrada?
El contenedor integrado no admite decoradores de forma nativa, pero puede lograrse manualmente usando delegados 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 aplicaciones que requieren muchos decoradores, un contenedor de terceros como Scrutor ofrece una API Decorate<TInterface, TDecorator>() más limpia.
22. ¿En qué se diferencia el middleware de los endpoint filters en minimal APIs?
El middleware se ejecuta para cada solicitud del pipeline, sin importar el endpoint. Los endpoint filters (introducidos en .NET 7) se ejecutan solo para los endpoints coincidentes, similar a los filtros de acción en MVC. Los filtros tienen acceso al contexto específico del endpoint y se registran por ruta o por grupo. Usa middleware para preocupaciones transversales como el logging y CORS; usa filtros para lógica específica del endpoint como la validación o la transformación.
23. ¿Qué es HybridCache en .NET 9?
HybridCache combina el almacenamiento en caché en memoria (L1) y distribuido (L2) detrás de una sola API. Maneja automáticamente la protección contra el cache stampede: cuando múltiples solicitudes concurrentes fallan en la caché para la misma clave, solo una ejecuta el método factory mientras las demás esperan. Esto reemplaza la coordinación manual entre IMemoryCache y IDistributedCache, que antes era propensa a errores.
24. ¿Cómo probar el middleware de forma aislada?
El middleware puede probarse usando DefaultHttpContext y un RequestDelegate personalizado. Crea una instancia del middleware, pásale un contexto simulado y verifica las propiedades de la respuesta.
[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 pruebas de integración, WebApplicationFactory<T> ofrece una prueba completa del pipeline que incluye el orden del middleware.
25. ¿Cuáles son los cambios de OpenAPI en .NET 9 y .NET 10?
.NET 9 reemplazó Swagger/Swashbuckle por la generación integrada de documentos OpenAPI mediante Microsoft.AspNetCore.OpenApi. .NET 10 actualizó a la biblioteca OpenAPI v2.0 con soporte para YAML, esquemas de tipos nullable mejorados (usando oneOf en lugar de la propiedad nullable) y mejor integración de los comentarios de documentación XML. Los documentos generados se sirven en /openapi/v1.json de forma predeterminada. Scalar o Swagger UI pueden agregarse como un paquete separado para documentación interactiva.
Practica explicar el pipeline de middleware en una pizarra: dibuja la solicitud descendiendo por cada middleware y la respuesta ascendiendo de regreso. Los entrevistadores de empresas como Microsoft, Accenture y consultoras usan con frecuencia este ejercicio para evaluar la profundidad de la comprensión.
Conclusión
- El orden de ejecución del middleware es determinista y crítico para la seguridad: manejo de excepciones primero, archivos estáticos antes de la autenticación, enrutamiento antes de la autorización
- El problema de la dependencia cautiva (scoped dentro de un singleton) es el bug de DI más común; habilita
ValidateScopesyValidateOnBuilden desarrollo - Los servicios con clave de .NET 8/9 eliminan la mayoría de las necesidades de contenedores DI de terceros o patrones de factory personalizados
- Las minimal APIs y los controladores coexisten; elige según la complejidad del proyecto, las convenciones del equipo y los requisitos de filtrado
- Estructura las minimal APIs usando métodos de extensión y grupos de rutas para mantener
Program.cslimpio - .NET 10 agrega validación integrada de minimal APIs, soporte de SSE mediante TypedResults y generación de OpenAPI mejorada
- Prueba el middleware de forma aislada con
DefaultHttpContext; usaWebApplicationFactorypara pruebas de integración
Practica estas preguntas con código real en el simulador de entrevistas .NET de SharpSkill, que cubre los módulos de minimal APIs, desarrollo de Web API y clean architecture.
¡Empieza a practicar!
Pon a prueba tu conocimiento con nuestros simuladores de entrevista y tests técnicos.
Etiquetas
Compartir
Artículos relacionados

Preguntas de Entrevista C# y .NET: Guía Completa 2026
Las 17 preguntas más frecuentes en entrevistas de C# y .NET. LINQ, async/await, inyección de dependencias, Entity Framework y buenas prácticas con respuestas detalladas.

.NET MAUI en 2026: Desarrollo Multiplataforma y Preguntas de Entrevista
Tutorial de .NET MAUI para 2026: desarrollo de aplicaciones multiplataforma con .NET 10, handlers, MVVM, HybridWebView. Incluye preguntas de entrevista con respuestas detalladas.

.NET 9 Blazor: Desarrollo Full-Stack con Blazor United en 2026
.NET 9 Blazor United combina renderizado estático SSR, Server y WebAssembly en un framework full-stack unificado. Tutorial práctico que cubre modos de renderizado, streaming, inyección por constructor y patrones listos para producción.