2012-04-24 44 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; 
    }