Внедрение и использование оболочки журнала для log4net

Этот вопрос связан с ответом Steven- здесь. Он предложил очень хорошую обертку для лесорубов. Я вставлю его код ниже:

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

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

    // More methods here.
}

Итак, мой вопрос в том, как правильно создать реализацию, которая прокси для log4net? Должен ли я просто добавить другой метод расширения журнала с параметром типа, а затем создать переключатель внутри? Используйте другой метод log4net в случае LoggingEventType?

И второй вопрос, как лучше всего использовать его позже в коде?

Потому что он написал:

(…) Вы можете легко создать реализацию ILogger (…) и настроить свой DI-контейнер так, чтобы он внедрялся в классы, у которых в конструкторе есть ILogger.

Означает ли это, что каждый класс, который будет регистрировать sth (так в основном каждый), должен иметь ILogger в своем конструкторе?

1 ответ

Решение

Итак, мой вопрос в том, как правильно создать реализацию, которая прокси для log4net?

Вы должны создать что-то вроде:

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.Severity == LoggingEventType.Debug)
            m_Adaptee.Debug(entry.Message, entry.Exception);
        else if(entry.Severity == LoggingEventType.Information)
            m_Adaptee.Info(entry.Message, entry.Exception);
        else if(entry.Severity == LoggingEventType.Warning)
            m_Adaptee.Warn(entry.Message, entry.Exception);
        else if(entry.Severity == LoggingEventType.Error)
            m_Adaptee.Error(entry.Message, entry.Exception);
        else
            m_Adaptee.Fatal(entry.Message, entry.Exception);
    }
}

Означает ли это, что каждый класс, который будет регистрировать sth (так в основном каждый), должен иметь ILogger в своем конструкторе?

Как я понимаю из ответа Стивенса: да, ты должен сделать это.

Каков наилучший способ использовать его позже в коде?

Если вы используете DI-контейнер, просто используйте DI-контейнер для отображения ILogger в Log4netAdapter, Вам также необходимо зарегистрироваться log4net.ILogили просто передайте экземпляр log4net logger в контейнер DI, чтобы внедрить его в конструктор Log4netAdapter.

Если вы не используете контейнер DI, т.е. вы используете Pure DI, то вы делаете что-то вроде этого:

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

ILogger logging_adapter = new Log4netAdapter(log);

var myobject = new MyClass(other_dependencies_here, logging_adapter);
Другие вопросы по тегам