在the documentation中的日志记录示例中,有一个如何将记录器注入控制器的示例:
public class TodoController : Controller
{
private readonly ITodoRepository _todoRepository;
private readonly ILogger _logger;
public TodoController(ITodoRepository todoRepository,
ILogger<TodoController> logger)
{
_todoRepository = todoRepository;
_logger = logger;
}
}
每次我将记录器注入此处时,DI框架是否会创建一个新的记录器?还有更好的方法吗?
答案 0 :(得分:7)
通过查看来源可以轻松回答这个问题。执行services.AddLogging()
时,默认行为是ILogger<T>
is registered as a singleton:
public static IServiceCollection AddLogging(this IServiceCollection services, Action<ILoggingBuilder> configure)
{
// …
services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>());
services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>)));
// …
}
所以不,只要应用程序正在运行,某个类型ILogger<T>
的{{1}}个实例就会被保留。因此,当向控制器中注入T
时,每次都会将相同的记录器实例传递给它。
当然这仅适用于记录器,但不适用于您的控制器本身。默认情况下,控制器在DI之外激活,但实际上具有范围生命周期。因此,在每个请求中,都会有一个新的控制器实例;但那个人将从之前获得记录器实例。
要回答你的上一个问题,还有更好的方法吗?没有。除了这个行为已经是一个好的事实(因为不需要新的记录器实例),使用记录的正确方法确实是将ILogger<TodoController>
注入类型ILogger<T>
,所以你获得正确分类的记录器实例。真的没有必要担心这里非常薄的记录器,因为你可能永远看不到背景中有太多昂贵的东西;)