实施和记录器包装的使用记录器

2023-09-06 10:18:07 作者:事了拂衣去

这个问题是关系到史蒂芬的回答 - 的此处。他提出了一个很好的记录器的包装。我会在下面贴了code:

 公共接口ILogger
{
    无效日志(LogEntry项);
}

公共静态类LoggerExtensions
{
    公共静态无效的登录(这ILogger记录器,字符串消息)
    {
        logger.Log(新LogEntry(LoggingEventType.Information,
            消息,NULL,NULL));
    }

    公共静态无效的登录(这ILogger记录仪,例外的例外)
    {
        logger.Log(新LogEntry(LoggingEventType.Error,
            exception.Message,空,异常));
    }

    //更多方法在这里。
}
 

所以,我的问题是什么是正确的方法来创建实现,代理到log4net的?我是不是应该加用类型参数另一个日志扩展方法,然后里面创建一个开关?如果 LoggingEventType

使用不同的log4net的方法 Win7系统封装制作的全过程

和第二个问题,什么是在code以后使用它的最好方法是什么?

由于他写道:

  

(...),你可以轻松地创建一个ILogger实现(...),并配置   您的DI容器中有一个ILogger类注入它自己   构造函数。

这是否意味着每一个类,将记录某事(所以基本上每一个),应该有 ILogger 在其构造?

解决方案   

所以,我的问题是什么是正确的方法来创建实现,代理到log4net的?

您应该创建是这样的:

 公共类Log4netAdapter:ILogger
{
    私人只读log4net.ILog m_Adaptee;

    公共Log4netAdapter(log4net.ILog适配)
    {
        m_Adaptee =适配;
    }

    公共无效日志(LogEntry项)
    {
        //这里调用m_Adaptee
        如果(entry.LoggingEventType == LoggingEventType.Information)
            m_Adaptee.Info(entry.Message,entry.Exception);
        否则,如果(entry.LoggingEventType == LoggingEventType.Warning)
            m_Adaptee.Warn(entry.Message,entry.Exception);
        否则,如果(entry.LoggingEventType == LoggingEventType.Error)
            m_Adaptee.Error(entry.Message,entry.Exception);
        其他
            m_Adaptee.Fatal(entry.Message,entry.Exception);
    }
}
 

  

这是否意味着每一个类,将记录某事(所以基本上每一个),应该有ILogger在其构造?

当我从史蒂文斯回答明白:是的,你应该这样做。

  

什么是在code以后使用它的最好方法是什么?

如果您使用的是DI容器,那么只要使用DI容器 ILogger 映射到 Log4netAdapter 。您还需要注册 log4net.ILog ,或者只给log4net的记录器实例的DI容器将其注入到Log4netAdapter构造。

如果您不使用DI容器,即使用纯DI 的,那么你做这样的事情:

 的ILog日志= log4net.LogManager.GetLogger(MyClass的);

ILogger logging_adapter =新Log4netAdapter(日志);

VAR为MyObject =新MyClass的(other_dependencies_here,logging_adapter);
 

This question is related to Steven’s answer - here. He proposed a very good logger wrapper. I will paste his code below:

public interface ILogger
{
    void Log(LogEntry entry);
}

public static class LoggerExtensions
{
    public static void Log(this ILogger logger, string message)
    {
        logger.Log(new LogEntry(LoggingEventType.Information,
            message, null, null));
    }

    public static void Log(this ILogger logger, Exception exception)
    {
        logger.Log(new LogEntry(LoggingEventType.Error, 
            exception.Message, null, exception));
    }

    // More methods here.
}

So, my question is what is the proper way to create implementation that proxies to log4net? Should I just add another Log extension method with type parameter and then create a switch inside? Use different log4net method in case of LoggingEventType ?

And second question, what is the best way to use it later in the code?

Because he wrote:

(…) you can easily create an ILogger implementation (…) and configure your DI container to inject it in classes that have a ILogger in their constructor.

Does that mean that every class that will log sth (so basically every), should have ILogger in its constructor?

解决方案

So, my question is what is the proper way to create implementation that proxies to log4net?

you should create something like:

public class Log4netAdapter : ILogger
{
    private readonly log4net.ILog m_Adaptee;

    public Log4netAdapter(log4net.ILog adaptee)
    {
        m_Adaptee = adaptee;
    }

    public void Log(LogEntry entry)
    {
        //Here invoke m_Adaptee
        if(entry.LoggingEventType == LoggingEventType.Information)
            m_Adaptee.Info(entry.Message, entry.Exception);
        else if(entry.LoggingEventType == LoggingEventType.Warning)
            m_Adaptee.Warn(entry.Message, entry.Exception);
        else if(entry.LoggingEventType == LoggingEventType.Error)
            m_Adaptee.Error(entry.Message, entry.Exception);
        else
            m_Adaptee.Fatal(entry.Message, entry.Exception);
    }
}

Does that mean that every class that will log sth (so basically every), should have ILogger in its constructor?

As I understand from Stevens answer: Yes, you should do this.

what is the best way to use it later in the code?

If you are using a DI container, then just use the DI container to map ILogger to Log4netAdapter. You also need to register log4net.ILog, or just give an instance of log4net logger to the DI container to inject it to the Log4netAdapter constructor.

If you don't use a DI container, i.e., you use Pure DI, then you do something like this:

ILog log = log4net.LogManager.GetLogger("MyClass");

ILogger logging_adapter = new Log4netAdapter(log);

var myobject = new MyClass(other_dependencies_here, logging_adapter);