注入ILogger <T>每次都会创建一个新的记录器吗?

Ste*_*phu 5 c# asp.net-core asp.net-core-2.0

在文档中的日志记录示例中,有一个示例如何将记录器注入控制器:

public class TodoController : Controller
{
    private readonly ITodoRepository _todoRepository;
    private readonly ILogger _logger;

    public TodoController(ITodoRepository todoRepository,
        ILogger<TodoController> logger)
    {
        _todoRepository = todoRepository;
        _logger = logger;
    }
}
Run Code Online (Sandbox Code Playgroud)

每次我将记录器注入此处时,DI框架是否会创建一个新的记录器?有没有更好的办法?

pok*_*oke 8

通过查看源代码可以轻松回答这个问题.执行此操作时services.AddLogging(),默认行为ILogger<T>是注册为单例:

public static IServiceCollection AddLogging(this IServiceCollection services, Action<ILoggingBuilder> configure)
{
    // …

    services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>());
    services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>)));

    // …
}
Run Code Online (Sandbox Code Playgroud)

所以不,只要应用程序正在运行,就会保留ILogger<T>某种类型的实例T.因此,当向ILogger<TodoController>控制器中注入时,每次都会将相同的记录器实例传递给它.

当然这仅适用于记录器,而不适用于您的控制器本身.默认情况下,控制器在DI之外激活,但实际上具有范围生命周期.因此,在每个请求中,都会有一个新的控制器实例; 但那个人将从之前获得记录器实例.

要回答你的上一个问题,有更好的方法吗?没有.除了这个行为已经是一个好的事实(因为不需要新的记录器实例),使用日志记录的正确方法确实是注入ILogger<T>类型T,因此您可以获得正确分类的记录器实例.真的没有必要担心这里非常薄的记录器,因为在后台发生了很多更昂贵的事情,你可能永远都看不到;)