Configurando e testando o serviço via DI
ResumoImplementamos
ILoggerManagersobre o provedor de logging e registramos o serviço no contêiner de DI comoSingleton. Depois validamos escrevendo logs a partir de um controller.
1. Objetivos de Aprendizagem#
- Implementar
ILoggerManagerreaproveitando oILogger<T>nativo. - Registrar o serviço no contêiner de DI com o tempo de vida correto.
- Injetar e testar o logger a partir de um controller.
2. Pré-requisitos#
- Interface
ILoggerManagerdefinida (tópico 16.5).
3. Conceito#
Injeção de Dependência (DI) é a técnica de fornecer as dependências de uma classe de fora, em vez de a classe criá-las. IoC (Inversão de Controle) é o princípio: o controle da criação passa para o contêiner. O porquê: baixo acoplamento e testabilidade — o controller não sabe qual implementação de log está sendo usada.
A implementação a seguir usa o próprio ILoggerFactory do framework, evitando dependência de terceiros e mantendo o log estruturado.
4. Mão na Massa#
4.1. Setup#
Nenhum pacote de terceiros é necessário — usamos Microsoft.Extensions.Logging, já presente.
4.2. Implementação Passo a Passo#
- Implemente a interface em
Catalog.LoggerService:
using Catalog.Contracts;
using Microsoft.Extensions.Logging;
namespace Catalog.LoggerService;
public sealed class LoggerManager : ILoggerManager
{
private readonly ILogger<LoggerManager> _logger;
public LoggerManager(ILogger<LoggerManager> logger) => _logger = logger;
public void LogInfo(string message) => _logger.LogInformation("{Message}", message);
public void LogWarn(string message) => _logger.LogWarning("{Message}", message);
public void LogDebug(string message) => _logger.LogDebug("{Message}", message);
public void LogError(string message) => _logger.LogError("{Message}", message);
}
- Registre no contêiner (método de extensão):
public static IServiceCollection ConfigureLoggerService(this IServiceCollection services) =>
services.AddSingleton<ILoggerManager, LoggerManager>();
- Chame no
Program.cs:
builder.Services.ConfigureLoggerService();
4.3. Executando#
Injete e use em um controller de teste:
[ApiController]
[Route("api/[controller]")]
public class WeatherController : ControllerBase
{
private readonly ILoggerManager _logger;
public WeatherController(ILoggerManager logger) => _logger = logger;
[HttpGet]
public IActionResult Get()
{
_logger.LogInfo("Requisição GET /weather recebida.");
_logger.LogDebug("Detalhe de depuração.");
return Ok(new { status = "ok" });
}
}
dotnet run
# em outro terminal:
curl http://localhost:5000/api/weather
No console você verá as mensagens nos níveis configurados.
5. Exemplo Completo#
// Program.cs (trecho)
builder.Services.ConfigureLoggerService();
builder.Services.ConfigureControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
6. Boas Práticas e Armadilhas#
| Faça | Evite |
|---|---|
Registrar o logger como Singleton (é thread-safe e sem estado) | Registrar como Scoped sem necessidade |
Usar templates estruturados ("{Message}") | Concatenar com $"..." perdendo os campos |
| Injetar a interface, não a implementação | Instanciar new LoggerManager(...) manualmente |
Atençãoníveis de log são filtrados por
appsettings.json. SeLogDebugnão aparece, verifique oLogLeveldo ambiente — em produçãoDebugnormalmente está desligado.
7. Segurança e Produção#
- Ajuste
LogLevel.DefaultparaInformationouWarningem produção;Debug/Tracepodem vazar detalhes internos. - Centralize logs (arquivo rotacionado, Seq, Elastic, Application Insights) e proteja o acesso a eles.
- Reforço de compliance: jamais logue segredos ou PII (LGPD).
8. Exercícios#
- Fácil: troque o
LogLevel.DefaultparaWarningemappsettings.Production.jsone observe o efeito. - Médio: substitua a implementação por uma baseada em Serilog sem alterar quem consome
ILoggerManager. - Desafio: escreva um teste unitário que verifica que o controller chama
LogInfo(use um mock deILoggerManager).
9. Resumo#
Implementamos ILoggerManager sobre o logging nativo, registramos como Singleton e validamos via controller. A abstração permite trocar o provedor sem tocar no restante do código.
10. Próximos Passos#
Módulo 17: estruturamos a aplicação com Onion Architecture, EF Core e as camadas de repositório e serviço.
11. Referências#
- Microsoft Learn — Injeção de dependência no ASP.NET Core
- Microsoft Learn — Logging no .NET
- Microsoft Learn — Provedores de logging