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");
}
}
我正在编写可能不干净的Logger属性。
您可以看到以下行看起来不干净。
new LoggerUtility<TestCode>().logger.Log(LogType.Info, "hello world");
有没有更好的方法来编写客户端代码?我希望与LogUtil松散耦合,而不是直接在我的客户端代码中使用它。
请告诉我。
由于
答案 0 :(得分:2)
注释中提供的答案是正确的(客户端应该依赖于接口ILogUtil
而不是直接具体实现)。还有许多其他问题:
每次登录邮件时,您都会实例化LoggerUtility<T>
类和 Logger
类的新实例。也许这里的东西应该是静态的?额外图层(LoggerUtility
)的重点是什么?
您对泛型(LoggerUtility<T>
)的使用并不完全有意义,因为您不必仅键入T
,也不会使用该信息。
实际上,编写自己的日志记录是其他人已经花费的努力 - 只需使用现有的实现。我可以为log4net
和NLog
担保,但如果您希望有灵活性,请在Castle.Services.Logging中找到适当的外观,其中包含适用于前面提到的实施的适配器(并且您可以自己写!)。
答案 1 :(得分:0)
取决于您希望日志包装器的行为有多复杂?
记录有多个级别,信息和例外是常态。
围绕使用Interfaces的答案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;
}