编写包装类以获得松耦合的更好方法

本文关键字:耦合 更好 方法 包装类 | 更新日期: 2023-09-27 18:32:19

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 进行松散耦合,而不是直接在我的客户端代码中使用它。

请让我知道。

谢谢

编写包装类以获得松耦合的更好方法

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

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

  • 你使用泛型(LoggerUtility<T>)并不完全有意义,因为你不仅限于键入T,而且你没有使用这些信息。

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

详细信息:是否有适用于 .NET 世界的日志记录外观?

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

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

围绕使用接口的答案是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;
    }