问题描述
这个问题与 Steven 的回答有关 - 此处.他提出了一个非常好的记录器包装器.我将在下面粘贴他的代码:
公共接口ILogger{无效日志(日志条目条目);}公共静态类 LoggerExtensions{公共静态无效日志(此 ILogger 记录器,字符串消息){logger.Log(new LogEntry(LoggingEventType.Information,消息,空));}公共静态无效日志(此 ILogger 记录器,异常异常){logger.Log(new LogEntry(LoggingEventType.Error,异常.消息,异常));}//这里有更多方法.}
所以,我的问题是创建代理 log4net 的实现的正确方法是什么?我应该添加另一个带有类型参数的日志扩展方法,然后在里面创建一个开关吗?在 LoggingEventType
的情况下使用不同的 log4net 方法?
第二个问题,在代码后面使用它的最佳方式是什么?
因为他写道:
(...) 您可以轻松创建 ILogger 实现 (...) 并配置您的 DI 容器将其注入到具有 ILogger 的类中构造函数.
这是否意味着每个类(基本上是每个)都应该在其构造函数中包含 ILogger
?
你应该创建类似的东西:
公共类 Log4netAdapter : ILogger{私有只读 log4net.ILog m_Adaptee;公共 Log4netAdapter(log4net.ILog 适配器){m_Adaptee = 适应者;}公共无效日志(LogEntry 条目){//这里调用m_Adapteeif(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);别的m_Adaptee.Fatal(entry.Message, entry.Exception);}}
这是否意味着每个类(基本上是每个)都应该在其构造函数中包含 ILogger?
我从史蒂文斯的回答中了解到:是的,你应该这样做.
稍后在代码中使用它的最佳方法是什么?
如果您使用的是 DI 容器,那么只需使用 DI 容器将 ILogger
映射到 Log4netAdapter
.您还需要注册log4net.ILog
,或者只是将log4net logger 的一个实例提供给DI 容器以将其注入到Log4netAdapter 构造函数中.
如果您不使用 DI 容器,即,您使用 PureDI,然后你做这样的事情:
ILog 日志 = log4net.LogManager.GetLogger("MyClass");ILogger logging_adapter = new Log4netAdapter(log);var myobject = new 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));
}
public static void Log(this ILogger logger, Exception exception)
{
logger.Log(new LogEntry(LoggingEventType.Error,
exception.Message, 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:
Does that mean that every class that will log sth (so basically every), should have ILogger
in its constructor?
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.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);
}
}
As I understand from Stevens answer: Yes, you should do this.
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);
这篇关于log4net的logger wrapper的实现和使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!