2012-12-04 2 views
8

Common.Logging for .NET을 사용하는 a project을 보면 어떤 클래스는 로거 인스턴스를 클래스 정적 멤버로 선언합니다. 예를 들어 :C#에서 내 Common.Logging 로거가 인스턴스 멤버 또는 정적이어야합니까?

public class SimpleExample : IExample 
{ 
    public virtual void Run() 
    { 
     ILog log = LogManager.GetLogger(typeof (SimpleExample)); 

     log.Info("------- Initializing ----------------------"); 

     // etc 
    } 
}  

하나의 방법 또는 기타를 선호하는 이유가 :

public class HelloJob : IJob 
{ 
    private static ILog _log = LogManager.GetLogger(typeof(HelloJob)); 

    public HelloJob() 
    { 
    } 

    public virtual void Execute(IJobExecutionContext context) 
    { 
     _log.Info(string.Format("Hello World! - {0}", System.DateTime.Now.ToString("r"))); 
    } 
} 

그리고 다른 클래스의

는 로거 인스턴스 멤버로 선언?

각 경우에 어떤 접근 방식을 권장합니까? 스레드 안전과 관련이 있습니까?

정적 "로거"멤버가있는 "로거"클래스를 선언하고 전체 프로젝트에서 전역 변수가있는 문제를 제외하고이 클래스를 사용하면 문제가 발생합니까?

답변

9

대부분의 로거는 스레드로부터 안전하며, 인스턴스 생성시 시간과 메모리 측면에서 거의 오버 헤드가 없습니다. 따라서 실제 질문은 프로그래밍 및 유지 관리의 관점에서 의미가 있어야합니다. 한편으로

, 로거는 개념적으로 당신의 클래스에 연결, 그리고 클래스의 예를에, 많은 사람들이 정적을 유지하는 것을 선호하기 때문에. 그것은 완전히 유효한 주장입니다. 예를 들어, HelloWorldJobHelloJob까지 확장되면,보다 구체적인 서브 클래스 인스턴스가 있다고하더라도 대부분의 사람들은 HelloJob의 코드로 작성된 로그 메시지가 HelloJob 클래스와 연결될 것으로 예상합니다. 정적 메소드에서 로거에 액세스 할 수 있으면 좋지만 정적 필드에없는 경우 불가능합니다.

반면에, HelloJob이 자체 로거 인스턴스를 가져와야하는 이유는 없습니다. 의존성 주입 대신 (단위 테스트 가능성, 추가 구성 가능성 및 간단한 코드) 많은 언급이 있습니다. 그래서 개인적으로 로거가 DI 프레임 워크에 의해 주입되도록 제안합니다.이 경우 인스턴스 당 필드를 참조해야합니다.

public class HelloJob : IJob 
{ 
    private readonly ILog _log; 

    public HelloJob(ILog log) 
    { 
     _log = log; 
    } 
    ... 
} 

귀하의 DI 프레임 워크는 실행시에 알고 세부 정보를 기반 로거를 설정하거나 예상되는 로그 메시지가 생성되어 있는지 확인하기 위해 단위 테스트에서 가짜 또는 조롱 로거를 제공 할 수 있습니다. 인스턴스 당 필드를 참조하더라도 클래스 별 (또는 싱글 톤) 인스턴스를 사용하는 것은 자유 롭습니다.이 클래스는이 클래스에 속할 필요가없는 세부 사항입니다. 관심사.

+0

'LogManager.GetLogger'는 아마도 내부적으로 의존성 주입을 통해 구현됩니다. 즉, 종속성은 로거 내에서 관리됩니다. 내 로거가 "인스턴스 당 필드"로 저장되어 각 인스턴스에 대해 오버 헤드가 발생하는 것을 원하지 않습니다. 클래스를 처음로드 할 때 정적으로 저장하면 나를 위해 작동합니다. –

+2

@ChrisSinclair : 인스턴스화 * 세부 사항 *이 LogManager.GetLogger에 의해 처리된다는 것은 사실입니다. Commons.Logging은 공통 로깅 인터페이스를 제공하므로 기본 프레임 워크, 구성 등을 자유롭게 전환 할 수 있습니다. 공장 패턴의 예, 종속성 삽입이 아닙니다. 팩토리 패턴은 수동 인스턴스화보다 많은 이점을 가지고 있지만, 종속성 삽입은 여전히 ​​추가적인 이점을 가지고 있습니다. DI 프레임 워크는 각 유형별로 로거를 재사용하도록 설정할 수 있으며 오버 헤드는 사실상 측정 할 수없는 시간의 90 %입니다. – StriplingWarrior

+0

Common.Logging 문서에 따르면 public static LogManagers는 스레드로부터 안전하지만 인스턴스 메서드는 없으므로이 대답에 어긋나게 보인다. http://netcommon.sourceforge.net/docs/2.0.0/api/html/Common.Logging-Common.Logging.LogManager.html – coderjoe

관련 문제