编写包装类以获得松耦合的更好方法
本文关键字:耦合 更好 方法 包装类 | 更新日期: 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
,而且你没有使用这些信息。
实际上,编写自己的日志记录外观是其他人已经花费的努力 - 只需使用现有的实现。我可以保证log4net
和NLog
,但是如果您希望具有灵活性,请在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;
}