c# asp.net - ILogger 또는 ILoggerFactory를 AspNet Core의 생성자에 전달 하시겠습니까?




dependency injection (2)

MS 문서 "ASP.NET 코어 로깅 소개" 는 생성자 주입의 두 가지 예를 제공합니다

  • ILogger 사용

    private readonly ILogger _logger;   
    public TodoController(ILogger<TodoController> logger)  
    { 
        _logger = logger;   
    }
  • ILoggerFactory

    private readonly ILogger _logger;  
    public TodoController( ILoggerFactory loggerFactory)  
    {  
        _logger = loggerFactory.CreateLogger<TodoController>();  
    }

내 질문은 내 컨트롤러에서 호출 된 하위 클래스로 전달해야하는 것입니다.

  • ILoggerFactory 를 컨트롤러 및 각 클래스 호출에서 호출 된 하위 클래스에 전달 LoggerFactoryExtensions.CreateLogger LoggerFactoryExtensions.CreateLogger<MyChildClass>() 또는

  • 부모 컨트롤러의 ILogger<MyController> 를 컨트롤러에서 생성되고 일반 매개 변수 ILogger가 아닌 각 자식 클래스에 전달합니다.

로그에서는 모든 클래스가 상위 컨트롤러에서 'MyController'카테고리를 사용하는 것이 아니라 각 클래스에 대해 개별 카테고리 'MyChildClass'를 보는 것이 더 좋습니다.
그러나 각 객체 생성의 CreateLogger는 값 비싼 연산이 될 수 있습니다 (예 : https://github.com/aspnet/Logging/issues/524 )

어떤 옵션을 권하고 싶습니까? 다른 접근법을 제안 해 주시겠습니까?


Answers

이것은 디자인 문제와 관련이 있습니다.

컨트롤러는 어쨌든 자식 클래스를 생성하면 안됩니다. 그것은 컨트롤러가 SRP (Single Responsibility Principle)를 상대해야한다는 우려가 아닙니다.

내 질문은 내 컨트롤러에서 호출 된 하위 클래스로 전달해야하는 것입니다.

로거를 분리하는 것이 선호된다면 자식 (종속) 클래스에 자체 로거가있는 것보다 실제로 다른 선택 사항이 없습니다.

하위 클래스에 자체 로거를 주입하게하십시오.

public class TodoRepository : ITodoRepository {
    private readonly ILogger logger; 

    public TodoRepository(ILogger<TodoRepository> logger) { 
        this.logger = logger;   
    }

    //...
}

그런 다음 하위 클래스를 컨트롤러에 삽입하십시오.

public class TodoController : Controller {
    private readonly ILogger logger;
    private readonly ITodoRepository todoRepository;

    public TodoController(ILogger<TodoController> logger, ITodoRepository todoRepository) {
        this.logger = logger;   
        this.todoRepository = todoRepository;
    }

    //...
}

그렇게하면 자식 클래스가 해결되고 컨트롤러에 주입 될 때 자식 로거가 해결됩니다.


이 특별한 경우에는 C ++과 C # 사이에 차이점이 있습니다. C ++에서는 객체가 초기화되지 않으므로 생성자 내부에서 virutal 함수를 호출하는 것이 안전하지 않습니다. C #에서는 클래스 객체가 만들어지면 모든 멤버가 초기화됩니다. 생성자에서 가상 함수를 호출 할 수 있지만 여전히 0 인 멤버는 액세스 할 수 있습니다. 멤버에 액세스 할 필요가 없다면 C #에서 가상 함수를 호출하는 것이 안전합니다.





c# logging dependency-injection asp.net-core