Resumen

Si trabajas con una Web API en .NET y quieres entender cómo registrar eventos sin acoplar tu código, la combinación de inyección de dependencias y logging te da una base sólida para escribir controladores limpios, testeables y fáciles de mantener. Aquí te muestro cómo configurar el logger nativo de .NET y cómo inyectarlo en tus controladores paso a paso.

¿Qué es la inyección de dependencias en .NET y por qué importa?

La inyección de dependencias es un patrón que te permite recibir objetos ya configurados desde fuera de tu clase, en lugar de instanciarlos tú mismo con new. En una Web API de .NET, esto se traduce en pedirle al framework que te entregue servicios listos para usar.

El flujo arranca en Program.cs, donde registras los servicios. Para el logging, basta con llamar a AddLogging y .NET ya tiene todo lo necesario para entregarte un logger en cualquier controlador o clase del proyecto [00:30].

¿Por qué evitar usar new para crear dependencias? Porque te obliga a instanciar el objeto cada vez y bloquea reemplazos. Si quieres usar un mock en pruebas unitarias, no podrás hacerlo si la clase crea su propia instancia internamente.

¿Cómo inyectar un ILogger en un controlador?

La forma más común es recibir el logger en el constructor del controlador. Defines una variable privada de tipo ILogger<TuControlador> y la asignas desde el constructor.

Tipar el logger con el nombre del controlador, por ejemplo ILogger<WeatherForecastController>, le indica al sistema que ese log pertenece a esa clase específica. Esto es útil cuando lees la consola y necesitas rastrear de dónde salió cada mensaje.

Una vez asignado, puedes invocar métodos como LogInformation dentro de cualquier acción del controlador:

csharp _logger.LogInformation("Returning list of weather forecast");

Al ejecutar la API y lanzar el request desde el archivo HTTP, el mensaje aparece en la consola confirmando que la dependencia llegó correctamente [02:45].

¿Se puede inyectar el logger sin usar el constructor?

Sí. .NET permite recibir el servicio directamente como parámetro del método usando el atributo [FromServices]. Esto le dice al framework: de la configuración de servicios que está en Program.cs, tráeme este específico.

Es una alternativa útil cuando solo necesitas la dependencia en una acción puntual y no quieres ensuciar el constructor. Eliminas la variable privada, quitas la asignación y dejas el logger como parámetro del método [03:50].

¿Cómo configurar los niveles de logging en appsettings?

La configuración de logs vive en el archivo appsettings.json (y también en appsettings.Development.json si quieres reglas distintas para ambiente de desarrollo). Ahí defines hasta qué nivel de severidad se imprime en consola.

Los niveles, de menor a mayor severidad, son:

  • Trace: el más detallado, muestra absolutamente todo.
  • Debug: información útil durante desarrollo.
  • Information: eventos normales del flujo.
  • Warning: advertencias que no detienen la ejecución.
  • Error: fallos que requieren atención.
  • Critical: errores graves del sistema.

Si configuras el nivel en Information, verás todo lo que sea Information o más severo. Si lo subes a Error, solo verás Error y Critical.

¿Qué pasa si configuro el nivel en Error y dejo un LogInformation? Ese mensaje no se imprime. El logger filtra todo lo que esté por debajo del nivel configurado, así que tu LogInformation queda invisible hasta que cambies la configuración o subas la severidad del log.

Para probarlo, basta con cambiar LogInformation por LogError y volver a ejecutar. Ahí verás el mensaje, pero ahora marcado como fail en consola, porque .NET interpreta visualmente el nivel de error para que destaque [05:40].

¿Cómo aplicar este conocimiento en tu propia API?

Un buen reto para fijar los conceptos es construir tu propia clase de logging personalizada. La idea es que repliques el flujo completo:

  1. Crea una clase, por ejemplo LoginAPI, con la lógica que quieras registrar.
  2. Regístrala en Program.cs como servicio, igual que AddLogging.
  3. Inyéctala en el controlador WeatherForecast por constructor o con [FromServices].
  4. Úsala en cada endpoint para registrar entradas y salidas.

Al hacerlo, vas a ver cómo el contenedor de dependencias de .NET resuelve automáticamente la instancia, sin que tengas que preocuparte por crearla ni destruirla. Esa es la magia detrás de un código desacoplado y listo para escalar.

¿Ya intentaste cambiar los niveles de log en tu propio proyecto? Cuéntame en los comentarios qué configuración te funcionó mejor y si lograste integrar tu propia clase de servicio.