[英]How to initialize .net Core ILogger or ILoggerFactory from .NET Framework and inject to a constructor in Class library built in .Net Core
I am consuming a Class Library which is built using .NET Core.我正在使用一个使用 .NET Core 构建的 Class 库。 The Library has only one public class with a constructor accepting ILoggerFactory and another overloaded constructor accepting ILogger.该库只有一个公共 class,其构造函数接受 ILoggerFactory,另一个重载构造函数接受 ILogger。 But I am consuming this library in a console app built using .NET Framework 4.7.但是我在使用 .NET Framework 4.7 构建的控制台应用程序中使用这个库。 My console app uses Log4Net for logging.我的控制台应用程序使用 Log4Net 进行日志记录。 But I need to inject the instance of ILogger or ILoggerFactory so that the class library log's error based on my log.config settings.但我需要注入 ILogger 或 ILoggerFactory 的实例,以便 class 库日志的错误基于我的 log.config 设置。
I tried as below我试过如下
ILogger logger = new LoggerFactory().CreateLogger(); ILogger 记录器 = new LoggerFactory().CreateLogger(); var contentManager = new ContentManager(logger); var contentManager = new ContentManager(记录器);
But I don't know how to pass the Log4Net instance to the LoggerFactory.但我不知道如何将 Log4Net 实例传递给 LoggerFactory。
private static ILog _log = LogManager.GetLogger(typeof(Program));
static void Main(string[] args)
{
ILogger logger = new LoggerFactory().CreateLogger<ContentManager>();
var contentManager = new ContentManager(logger);
contentManager.Run();
}
I don't find anything getting logged and ContentManager doesn't throw any exceptions.我没有发现任何记录,ContentManager 也没有抛出任何异常。 I know that the ILogger instance doesn't know anything about Log4Net from my console app, how I need to pass the Log4Net instance?我知道 ILogger 实例对我的控制台应用程序中的 Log4Net 一无所知,我需要如何传递 Log4Net 实例? Need help on this.在这方面需要帮助。
The answer from Dan S is a great general answer with good example. Dan S的回答是一个很好的一般性回答,有很好的例子。 To implement this specifically for log.net you could use a class like this:要专门为 log.net 实现此功能,您可以像这样使用 class:
public class Log4netAdapter<TCategoryName> : ILogger<TCategoryName>
{
private readonly ILog _logger = LogManager.GetLogger(typeof(TCategoryName));
public IDisposable BeginScope<TState>(TState state)
{
return null; // log4net does not have scope capability
}
public bool IsEnabled(LogLevel logLevel)
{
switch (logLevel)
{
case LogLevel.Trace:
case LogLevel.Debug:
return _logger.IsDebugEnabled;
case LogLevel.Information:
return _logger.IsInfoEnabled;
case LogLevel.Warning:
return _logger.IsWarnEnabled;
case LogLevel.Error:
return _logger.IsErrorEnabled;
case LogLevel.Critical:
return _logger.IsFatalEnabled;
case LogLevel.None:
default:
return false;
}
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel)) return;
if (formatter == null) throw new ArgumentNullException(nameof(formatter));
var message = formatter(state, exception);
if (!string.IsNullOrEmpty(message) || exception != null)
{
switch (logLevel)
{
case LogLevel.None:
break;
case LogLevel.Trace:
case LogLevel.Debug:
_logger.Debug(message, exception);
break;
case LogLevel.Information:
_logger.Info(message, exception);
break;
case LogLevel.Warning:
_logger.Warn(message, exception);
break;
case LogLevel.Error:
_logger.Error(message, exception);
break;
case LogLevel.Critical:
_logger.Fatal(message, exception);
break;
}
}
}
}
Then reference the packages log.net
and Microsoft.Extensions.Logging
(or Microsoft.Extensions.Logging.Abstractions
if you are creating this in a library).然后引用包log.net
和Microsoft.Extensions.Logging
(或Microsoft.Extensions.Logging.Abstractions
,如果您在库中创建它)。
To use the adapter when instantiating a class using Microsoft.Extensions.Logging (and your project is not using dependency injection):要在使用 Microsoft.Extensions.Logging 实例化 class 时使用适配器(并且您的项目未使用依赖注入):
var logger = new Log4netAdapter<NewClassLibrary>();
var newClassLibrary = new NewClassLibrary(logger);
Try the Adapter Pattern to facilitate delegation to Log4Net. 尝试使用适配器模式以便于委派到Log4Net。 I'm not familiar with Log4Net but I think you'll understand this example: 我不熟悉Log4Net,但我想你会理解这个例子:
class MyLoggerAdapter : Library.ILogger
{
private readonly ILog _delegation;
public MyLoggerAdapter(ILog delegation)
{
_delegation = delegation;
}
public void ILogger.Debug(string msg, params object[] p)
{
_delegation.Debug(msg, p);
}
}
Then in your code you can do this: 然后在您的代码中,您可以这样做:
private static ILog _log = LogManager.GetLogger(typeof(Program));
static void Main(string[] args)
{
MyLoggerAdapter logAdapter = new MyLoggerAdapter(_log);
var contentManager = new ContentManager(logAdapter);
contentManager.Run();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.