2012-04-24 53 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 2012-04-24 19:30:44

+0

我該怎麼做? – 2012-04-24 20:45:19

+0

讓記錄器的客戶端依賴'ILogUtil'而不是'LogUtil ',即'ILogUtil logger = GetLogger();'而不是'LogUtil = GetLogger();'。然後,如果需要,可以更改實現。或者,您可以直接依賴log4net(或其ILog接口),因爲您不太可能需要更改記錄器實現。 – Lee 2012-04-24 21:06:42

回答

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(不要重複自己)的原則。

如果你發現你的代碼看起來非常重複,那麼也許除了使用注入和接口等標準外,還可以實現一個圍繞錯誤處理的Generic包裝。

泛型允許您分離解決方案的邏輯並允許重用,接口允許您將日誌記錄的概念從物理實現中分離出來。

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; 
    }