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");

    }

}

我正在编码可能不干净的 Logger 属性。

如您所见,以下行看起来并不干净。

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

有没有更好的方法来编写客户端代码?我想与 LogUtil 松耦合,而不是直接在我的客户端代码中使用它。

请告诉我。

谢谢

4

2 回答 2

2

评论中提供的答案是正确的(客户应该依赖接口ILogUtil而不是直接依赖具体实现)。还有无数其他问题:

  • 每次记录消息时,您都会实例化LoggerUtility<T>该类该类的一个新实例。Logger也许这里的东西应该是静态的?额外层 ( LoggerUtility) 的意义何在?

  • 您对泛型 ( LoggerUtility<T>) 的使用并不完全有意义,因为您不仅限于 type T,而且您没有使用该信息。

实际上,编写自己的日志外观是其他人已经花费的努力 - 只需使用现有的实现即可。我可以同时保证log4netNLog,但是如果您希望具有灵活性,请在Castle.Services.Logging中选择适当的外观,它具有前面提到的实现的适配器(您可以编写自己的!)。

更多信息在这里:.NET 世界是否有日志外观?

于 2012-04-24T22:22:14.733 回答
0

取决于您希望日志包装器的行为有多复杂?

日志记录有多个级别,信息和异常是常态。

围绕使用接口的答案是 100% 正确的,但也有 DRY 的原则(不要重复自己)。

如果您发现您的代码看起来非常重复,就像我的一样,那么也许除了使用注入和接口等标准之外,还可以实现一个通用包装器来处理错误。

泛型允许您分离解决方案的逻辑并允许重用,接口允许您将日志记录的概念与物理实现分离。

  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;
    }
于 2017-09-06T08:24:23.170 回答