此问题与Steven的答案相关 - here。他提出了一个非常好的记录器包装器。我将在下面粘贴他的代码:
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.
}
所以,我的问题是创建实现代理Microsoft.Extensions.Logging 的正确方法是什么,以后在代码中使用它的最佳方式是什么
注意:此问题是this question about log4net的副本,但现在特定于Microsoft.Extensions.Logging。
答案 0 :(得分:7)
所以,我的问题是创建代理Microsoft.Extensions.ILogger的实现的正确方法是什么?
你应该创建类似的东西:
public sealed class MicrosoftLoggingAdapter : ILogger
{
private readonly Microsoft.Extensions.ILogger adaptee;
public MicrosoftLoggingAdapter (Microsoft.Extensions.ILogger adaptee) =>
this.adaptee = adaptee;
public void Log(LogEntry e) =>
adaptee.Log(ToLevel(e.Severity), 0, e.Message, e.Exception, (s, _) => s);
private static LogLevel ToLevel(LoggingEventType s) =>
s == LoggingEventType.Debug ? LogLevel.Debug :
s == LoggingEventType.Information ? LogLevel.Information :
s == LoggingEventType.Warning ? LogLevel.Warning :
s == LoggingEventType.Error ? LogLevel.Error :
LogLevel.Critical;
}
以后在代码中使用它的最佳方法是什么?
如果您使用DI容器,则只需使用DI容器将ILogger
映射到MicrosoftLoggingAdapter
。您还需要注册Microsoft.Extensions.ILogger
,或者只是将一个MS logger实例提供给DI容器,以将其注入MicrosoftLoggingAdapter构造函数。
如果您不使用DI容器,即使用Pure DI,那么您可以执行以下操作:
var logger = loggerFactory.CreateLogger("Application");
ILogger logging_adapter = new MicrosoftLoggingAdapter(logger);
var myobject = new MyClass(other_dependencies_here, logging_adapter);
答案 1 :(得分:0)
这是我的解决方案。不太像史蒂文的。但是不完全一样。而且我倾向于dotNetCore,但是在dotnetFW中可以完成相同的事情。
DotNetCoreLogger是“ MY” ILogger的具体。然后将“ Microsoft” ILogger(Microsoft.Extensions.Logging.ILogger)注入“我的”具体记录器中。
还有一个SOF答案,“启发”了“我”的日志记录抽象...。从DotNetFramework(经典)转到DotNotCore之后,我很高兴我做了一个“我的” ILogger抽象。
using System;
namespace MyApplication.Infrastructure.Logging.LoggingAbstractBase
{
public interface ILogger
{
void Log(LogEntry entry);
void Log(string message);
void Log(Exception exception);
}
}
namespace MyApplication.Infrastructure.Logging.LoggingAbstractBase
{
public enum LoggingEventTypeEnum
{
Debug,
Information,
Warning,
Error,
Fatal
};
}
using System;
namespace MyApplication.Infrastructure.Logging.LoggingAbstractBase
{
public class LogEntry
{
public readonly LoggingEventTypeEnum Severity;
public readonly string Message;
public readonly Exception Exception;
public LogEntry(LoggingEventTypeEnum severity, string message, Exception exception = null)
{
if (message == null) throw new ArgumentNullException("message");
if (message == string.Empty) throw new ArgumentException("empty", "message");
this.Severity = severity;
this.Message = message;
this.Exception = exception;
}
}
}
using System;
using Microsoft.Extensions.Logging;
namespace MyApplication.Infrastructure.Logging.LoggingCoreConcrete
{
public class DotNetCoreLogger<T> : MyApplication.Infrastructure.Logging.LoggingAbstractBase.ILogger
{
private readonly ILogger<T> concreteLogger;
public DotNetCoreLogger(Microsoft.Extensions.Logging.ILogger<T> concreteLgr)
{
this.concreteLogger = concreteLgr ?? throw new ArgumentNullException("Microsoft.Extensions.Logging.ILogger is null");
}
public void Log(MyApplication.Infrastructure.Logging.LoggingAbstractBase.LogEntry entry)
{
if (null == entry)
{
throw new ArgumentNullException("LogEntry is null");
}
else
{
switch (entry.Severity)
{
case LoggingAbstractBase.LoggingEventTypeEnum.Debug:
this.concreteLogger.LogDebug(entry.Message);
break;
case LoggingAbstractBase.LoggingEventTypeEnum.Information:
this.concreteLogger.LogInformation(entry.Message);
break;
case LoggingAbstractBase.LoggingEventTypeEnum.Warning:
this.concreteLogger.LogWarning(entry.Message);
break;
case LoggingAbstractBase.LoggingEventTypeEnum.Error:
this.concreteLogger.LogError(entry.Message, entry.Exception);
break;
case LoggingAbstractBase.LoggingEventTypeEnum.Fatal:
this.concreteLogger.LogCritical(entry.Message, entry.Exception);
break;
default:
throw new ArgumentOutOfRangeException(string.Format("LogEntry.Severity out of range. (Severity='{0}')", entry.Severity));
}
}
}
public void Log(string message)
{
this.concreteLogger.LogInformation(message);
}
public void Log(Exception exception)
{
this.concreteLogger.LogError(exception.Message, exception);
}
}
}
/* IoC/DI below */
private static System.IServiceProvider BuildDi(Microsoft.Extensions.Configuration.IConfiguration config)
{
//setup our DI
IServiceProvider serviceProvider = new ServiceCollection()
.AddLogging()
.AddSingleton<IConfiguration>(config)
.AddSingleton<MyApplication.Infrastructure.Logging.LoggingAbstractBase.ILogger, MyApplication.Infrastructure.Logging.LoggingCoreConcrete.DotNetCoreLogger<Program>>()
.BuildServiceProvider();
//configure console logging
serviceProvider
.GetService<ILoggerFactory>()
.AddConsole(LogLevel.Debug);
return serviceProvider;
}