2017-12-20 27 views
4

는 컨트롤러에 로거를 주입하는 방법을 예를 들어 있습니다 :ILogger <T>을 주입 할 때마다 매번 새로운 로거가 생성됩니까? <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?tabs=aspnetcore2x" rel="nofollow noreferrer">the documentation</a>에서 로깅 샘플에

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

    public TodoController(ITodoRepository todoRepository, 
     ILogger<TodoController> logger) 
    { 
     _todoRepository = todoRepository; 
     _logger = logger; 
    } 
} 

는 DI 프레임 워크는 내가 여기에 같은으로 로거를 주입 할 때마다 새로운 로거를 만들 수 있습니까? 더 좋은 방법이 있습니까?

+1

ILogger 구현이 어떻게 등록되었는지에 따라 다릅니다. – user3292642

답변

6

이것은 소스를 보면 쉽게 알 수 있습니다.

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

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

    // … 
} 

그래서 아니, 특정 유형의 T에 대한 ILogger<T> 인스턴스가 한 응용 프로그램이 실행되는 동안 주변에 보관됩니다 : 당신이 services.AddLogging() 할 때, 기본 동작은 ILogger<T> is registered as a singleton 것입니다. 따라서 컨트롤러에 ILogger<TodoController>을 삽입하면 매번 동일한 로거 인스턴스가 전달됩니다.

물론 이것은 로거에만 적용되지만 컨트롤러 자체에는 적용되지 않습니다. 기본적으로 컨트롤러는 DI 외부에서 활성화되지만 유효 기간이 유효하게 유지됩니다. 그래서 모든 요청마다 새로운 컨트롤러 인스턴스가 생깁니다. 하지만 그때부터 로거 인스턴스를 가져올 것입니다.

마지막 질문에 대답하려면 더 좋은 방법이 있습니까? 새 로거 인스턴스가 필요 없기 때문에이 동작이 이미 좋은 것일뿐 아니라 실제로 로깅을 사용하는 적절한 방법은 T 유형에 ILogger<T>을 삽입하므로 올바르게 분류 된 로거 인스턴스를 얻을 수 있습니다. 백그라운드에서 매우 많은 비용이 드는 일들이있을 때 매우 얇은 로거에 대해 걱정할 필요가 없습니다.