2012-04-24 4 views
0
class LogUtil<T> : ILogUtility 
{ 
    log4net.ILog log; 

    public LogUtil() 
    { 
     log = log4net.LogManager.GetLogger(typeof(T).FullName); 
    } 

    public void Log(LogType logtype, string message) 
    { 
     Console.WriteLine("logging coming from class {0} - message {1} " , typeof(T).FullName, message); 
    } 
} 

public class Logger 
{ 
    ILogUtility _logutility; 

    public Logger(ILogUtility logutility) 
    { 
     _logutility = logutility; 
    } 


    public void Log(LogType logtype, string message) 
    { 
     _logutility.Log(logtype, message); 
    } 


} 

유연성이 있어야하며 앞으로 LogUtil 클래스를 제거하고 다른 것을 사용하는 기능이 있어야합니다. 다음과 같이느슨한 결합을 얻기 위해 래퍼 클래스를 작성하는 더 좋은 방법

그래서 나는 LoggerUtility 래퍼 클래스를 작성 :

class LoggerUtility<T> 
{ 
    public Logger logger 
    { 
     get 
     { 

      LogUtil<T> logutil = new LogUtil<T>(); 

      Logger log = new Logger(logutil); 

      return log; 
     } 
    } 
} 

내 클라이언트 코드를 다음과 같이 내가 로거 속성을 코딩하고

public class TestCode 
{ 
    public void test() 
    { 

     new LoggerUtility<TestCode>().logger.Log(LogType.Info, "hello world"); 

    } 

} 

깨끗하지 않을 수있다.

다음 줄이 깨끗하게 보이지 않는 것을 알 수 있습니다.

new LoggerUtility<TestCode>().logger.Log(LogType.Info, "hello world"); 

클라이언트 코드를 작성하는 더 좋은 방법이 있습니까? LogUtil과의 느슨한 결합을 원하고 클라이언트 코드에서 직접 사용하지 않습니다.

알려 주시기 바랍니다.

감사

+0

왜'LogUtil '에 의해 구현되는'ILogUtil' 인터페이스에 대한뿐만 아니라 코드? – Lee

+0

어떻게해야합니까? –

+0

Logger의 클라이언트가'LogUtil '대신에'ILOGUtil'에 의존하게하려면'LogUtil = GetLogger();'대신'ILOGUtil logger = GetLogger(); 필요한 경우 구현을 변경할 수 있습니다. 또는 로거 구현을 변경하지 않아도되기 때문에 log4net (또는 ILOG 인터페이스)에 직접 의존 할 수 있습니다. – Lee

답변

2

의견에서 제공하는 대답은 올바른 (클라이언트 인터페이스 ILogUtil보다는 직접 구체적인 구현에 의존한다)입니다. 당신은 새로운 기능 LoggerUtility<T> 클래스 의 인스턴스와Logger 클래스는 메시지를 로그인 할 때마다 인스턴스화하고

  • : 다른 문제의 무수가있다. 여기 뭔가가 정적일까요? 추가 레이어의 요점은 무엇입니까 (LoggerUtility)?

  • 제네릭 (LoggerUtility<T>)을 사용하는 것은 완전히 이해가되지 않습니다. 단지 T을 입력하는 것이 아니기 때문에 해당 정보를 사용하지 않아도됩니다.

실제로는 자신 만의 로깅 외관을 작성하는 것은 다른 사람들이 이미 사용한 노력입니다. 기존 구현을 사용하는 것입니다. log4netNLog을 모두 보증 할 수 있지만 유연성을 원하는 경우 Castle.Services.Logging에 올바른 외관을 사용해야합니다. 이전에 언급 한 구현을위한 어댑터가 있고 직접 작성할 수도 있습니다.

자세한 내용은 여기 정보 : Is there a logging facade for the .NET world?

0

당신이 당신의 로깅 래퍼가 작동하는 방법을 정교에 따라 다름?

로깅에는 여러 수준이 있으며 정보 및 예외가 일반적입니다.

인터페이스를 사용하여 해결되는 답변은 100 % 정확하지만 DRY (교대로 반복하지 마십시오)의 교장이 있습니다.

코드가 매우 반복적 인 것처럼 보이면 Injection 및 Interfaces와 같은 표준을 사용하는 것 외에 오류 처리를위한 일반 래퍼를 구현할 수도 있습니다.

Generics를 사용하면 솔루션 논리를 분리하고 재사용 할 수 있으므로 인터페이스를 사용하면 물리적 구현에서 로깅의 개념을 분리 할 수 ​​있습니다.

public static output ExecuteBlockwithLogging<output, input, config>(ExeBlock<output, input, config> exeBlock, input InputForExeBlock, ILoggingBlock logger) 
    { 

     exeBlock.Execute(InputForExeBlock); 

     if ((exeBlock.logEntries != null) && (exeBlock.logEntries.Length > 0)) 
     { 
      logger.Execute(exeBlock.logEntries); 
     } 


     if ((exeBlock.exceptions != null) && (exeBlock.exceptions.Length > 0)) 
     { 
      foreach (var e in exeBlock.exceptions) 
      { 

       var dictionaryData = new Dictionary<string, string>(); 
       if (e.Data.Count > 0) 
       { 
        foreach (DictionaryEntry d in e.Data) 
        { 
         dictionaryData.Add(d.Key.ToString(), d.Value.ToString()); 
        } 
       } 

       var messages = e.FromHierarchy(ex => ex.InnerException).Select(ex => ex.Message); 


       LoggingEntry LE = new LoggingEntry 
       { 
        description = e.Message, 
        exceptionMessage = String.Join(Environment.NewLine, messages), 
        source = exeBlock.GetType().Name, 
        data = dictionaryData 
       }; 

       logger.Execute(new LoggingEntry[] { LE }); 
      } 
      return default(output); 
     } 

     return exeBlock.Result; 
    } 
관련 문제