C# 编写包装器类以获得松散耦合的更好方法 class LogUtil:ILogUtility { log4net.ILog日志; 公共LogUtil() { log=log4net.LogManager.GetLogger(typeof(T).FullName); } 公共无效日志(日志类型、日志类型、字符串消息) { WriteLine(“来自类{0}-message{1}的日志记录,typeof(T).FullName,message); } } 公共类记录器 { 我的直觉(logutility);; 公共记录器(ILogUtility) { _logutility=logutility; } 公共无效日志(日志类型、日志类型、字符串消息) { _logutility.Log(日志类型,消息); } }

C# 编写包装器类以获得松散耦合的更好方法 class LogUtil:ILogUtility { log4net.ILog日志; 公共LogUtil() { log=log4net.LogManager.GetLogger(typeof(T).FullName); } 公共无效日志(日志类型、日志类型、字符串消息) { WriteLine(“来自类{0}-message{1}的日志记录,typeof(T).FullName,message); } } 公共类记录器 { 我的直觉(logutility);; 公共记录器(ILogUtility) { _logutility=logutility; } 公共无效日志(日志类型、日志类型、字符串消息) { _logutility.Log(日志类型,消息); } },c#,generics,log4net,C#,Generics,Log4net,我需要具有灵活的功能,并且能够在将来删除LogUtil类并使用其他东西 因此,我编写了LoggerUtility包装类,如下所示: class LogUtil<T> : ILogUtility { log4net.ILog log; public LogUtil() { log = log4net.LogManager.GetLogger(typeof(T).FullName); } public void Log(LogT

我需要具有灵活的功能,并且能够在将来删除LogUtil类并使用其他东西

因此,我编写了LoggerUtility包装类,如下所示:

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


}
class LoggerUtility<T>
{
    public Logger logger
    {
        get
        {

            LogUtil<T> logutil = new LogUtil<T>();

            Logger log = new Logger(logutil);

            return log;
        }
    }
}
类日志实用程序
{
公共记录器
{
得到
{
LogUtil LogUtil=新的LogUtil();
记录器日志=新记录器(logutil);
返回日志;
}
}
}
我的客户代码如下:

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


}
class LoggerUtility<T>
{
    public Logger logger
    {
        get
        {

            LogUtil<T> logutil = new LogUtil<T>();

            Logger log = new Logger(logutil);

            return log;
        }
    }
}
公共类测试代码
{
公开无效测试()
{
新的LoggerUtility().logger.Log(LogType.Info,“hello world”);
}
}
我正在对可能不干净的财产进行编码

正如你们所看到的,下面这条线看起来并不干净

public class TestCode
{
    public void test()
    {

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

    }

}
new LoggerUtility().logger.Log(LogType.Info,“hello world”);
有没有更好的方法来编写客户机代码?我希望与LogUtil松散耦合,而不是直接在客户机代码中使用它

请让我知道


谢谢

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

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

  • 您对泛型(
    LoggerUtility
    )的使用并不完全有意义,因为您不必只键入
    t
    ,也不需要使用这些信息

实际上,编写自己的日志facade是其他人已经付出的努力——只需使用现有的实现即可。我可以保证
log4net
NLog
,但如果您希望具有灵活性,请在中选择一个合适的facade,它为前面提到的实现提供适配器(您可以自己编写!)


此处的更多信息:

取决于您希望日志包装器的性能有多复杂

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

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

如果您发现您的代码看起来非常重复,就像我的代码一样,那么在使用注入和接口等标准的基础上,还可以围绕错误处理实现一个通用包装器

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

new LoggerUtility<TestCode>().logger.Log(LogType.Info, "hello world");
publicstaticoutput ExecuteBlockwithLogging(ExeBlock ExeBlock、INPUTPUTFOREXEBLOCK、ILOGINGBLOCK记录器)
{
Execute(InputForExeBlock);
if((exeBlock.logEntries!=null)&&(exeBlock.logEntries.Length>0))
{
logger.Execute(exeBlock.logEntries);
}
如果((exeBlock.exceptions!=null)&&(exeBlock.exceptions.Length>0))
{
foreach(exeBlock.exceptions中的变量e)
{
var dictionaryData=新字典();
如果(e.Data.Count>0)
{
foreach(字典在e.Data中输入d)
{
Add(d.Key.ToString(),d.Value.ToString());
}
}
var messages=e.FromHierarchy(ex=>ex.InnerException);
LoggingEntry LE=新的LoggingEntry
{
description=e.消息,
exceptionMessage=String.Join(Environment.NewLine,messages),
source=exeBlock.GetType().Name,
数据=字典数据
};
执行(新的LoggingEntry[]{LE});
}
返回默认值(输出);
}
返回exeBlock.Result;
}

为什么不针对
LogUtil
实现的
ILogUtil
接口编码?让记录器的客户端依赖于
ILogUtil
而不是
LogUtil
,即
ILogUtil logger=GetLogger()而不是
LogUtil=GetLogger()。然后,如果需要,您可以更改实现。或者,您可以直接依赖log4net(或其
ILog
接口),因为您不太可能需要更改记录器实现。