前言
我在WPF + Prism中使用NLog,但是我想在每个模块(类)中使用Microsoft.Extensions.Logging.ILogger,该如何实现。
背景
我开始制作一个示例程序,因为我希望能够使用WPF + Prism制作一个应用程序。
因为Prism官方已经将Prism.Logging从Prism框架中删除,目前选择的日志框架是NLog,通过使用Microsoft.Extensions.Logging.ILogger可以实现。虽然这可能还不是最好的用法,但是在大多数情况下,只要您知道日志级别(INFO / DEBUG / ERROR)就足够了。
对于要使用日志输出的函数,我将ILogger传递给该类的构造函数,并让Prism解决该问题。这就是它的用法。
//指定ILogger构造函数的参数,它获得注入Prism
public MainWindowViewModel(ILogger logger)
{
logger.LogInformation("DI logger in MainWindowViewModel.cs");
}
当然,您需要为Prism的DI容器注册ILogger的实现类。使用logger,您只需要一个实现类的实例,因此
containerRegistry.RegisterInstance<Microsoft.Extensions.Logging.ILogger>(logger);
您作为参数传递的记录器,必须从Microsoft.Extensions.Logging.ILogger继承。...哦,您如何从NLog制作Microsoft.Extensionis.Logging.ILogger?
在NLog Getting Started中,
- .NET Framework→直接使用NLog而不使用DI的示例
- .ASP.NET Core→WebHost的UseNLog()示例
- .NET Core控制台→Microsoft的DI容器(ServiceCollection)的AddNLog()示例
已列出。在ASP.NET Core示例中,未明确提及DI容器名称,但应使用ServiceCollection。无论如何,使用Prism的DI容器很难知道该怎么做。
因为UseNLog()和AddNLog()是NLog→(Microsoft)ILogger,所以我认为应该有这样的功能,当我再次查看.NET Core控制台示例时using NLog.Extensions.Logging;
,我注意到它已经完成了。似乎有一个函数可以执行NLog→(Microsoft)ILogger。
如果您要求不高,您会发现可以使用如下代码:不敢理解从NLog到(Microsoft)ILogger的转换using NLog.Extensions.Logging;
。
*使用NuGet获取NLog.Extensions.Logging
*创建NLog.config并将其复制到输出目录:如果新,请不要忘记复制它!
App.xaml.cs
using LoggerSample.Views;
using Prism.Ioc;
using Prism.Modularity;
using System.Windows;
using Microsoft.Extensions.Logging;
namespace LoggerSample
{
public partial class App
{
//略
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
#if false
// NLog.configの設定からプログラムコードで変更
var config = new NLog.Config.LoggingConfiguration();
var logfile = new NLog.Targets.FileTarget("logfile") { FileName = "log/file.txt" };
config.AddRule(NLog.LogLevel.Debug, NLog.LogLevel.Fatal, logfile);
NLog.LogManager.Configuration = config;
#endif
var factory = new NLog.Extensions.Logging.NLogLoggerFactory();
Microsoft.Extensions.Logging.ILogger logger = factory.CreateLogger("");
containerRegistry.RegisterInstance<Microsoft.Extensions.Logging.ILogger>(logger);
// DIコンテナから取り出せるよね?
var log = Container.Resolve<Microsoft.Extensions.Logging.ILogger>();
log.LogInformation("Test in RegsiterTypes()");
}
}
}
App.xaml.cs
using LoggerSample.Views;
using Prism.Ioc;
using Prism.Modularity;
using System.Windows;
using Microsoft.Extensions.Logging;
namespace LoggerSample
{
public partial class App
{
//略
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
#if false
//从该组NLog.Config的程序代码中的变化
var config = new NLog.Config.LoggingConfiguration();
var logfile = new NLog.Targets.FileTarget("logfile") { FileName = "log/file.txt" };
config.AddRule(NLog.LogLevel.Debug, NLog.LogLevel.Fatal, logfile);
NLog.LogManager.Configuration = config;
#endif
var factory = new NLog.Extensions.Logging.NLogLoggerFactory();
Microsoft.Extensions.Logging.ILogger logger = factory.CreateLogger("");
containerRegistry.RegisterInstance<Microsoft.Extensions.Logging.ILogger>(logger);
// 从集合Container中获取ILogger对象
var log = Container.Resolve<Microsoft.Extensions.Logging.ILogger>();
log.LogInformation("Test in RegsiterTypes()");
}
}
}
看起来就2020-08-06 05:34:00.5122|INFO||Test in RegsiterTypes()
这么简单,我不知道日志输出的位置(模块名称)。
这var logger = LogManager.GetCurrentClassLogger();
是因为上面的代码并未说明它是NLog的可靠用法。可以通过将$ {callsite}放在NLogConfig的布局中来解决。就我而言,${callsite:includeNamespace=false}
就足够了。
NLog.config
首先添加negut包Nlog.Config:将一下配置替换Nlog.Config内容
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off"
internalLogFile="c:\nlog\nlog-internal.log">
<variable name="varDataFolderPath" value="${basedir}/logs"/>
<variable name="varLayHeader" value="${longdate}|${level}"/>
<variable name="varLayMiddle" value="${callsite-linenumber}|${callsite:includeSourcePath=false:methodName=false}"/>
<variable name="varLayBack" value="${message}|${exception:format=toString}"/>
<targets>
<target name="logFile"
xsi:type="File"
encoding="utf-8"
maxArchiveFiles="100"
archiveEvery="Day"
archiveNumbering="Date"
archiveDateFormat="yyyyMMdd"
archiveFileName="${varDataFolderPath}/archives/log.{#}.txt"
fileName="${varDataFolderPath}/nlog.txt"
layout="${varLayHeader}|${varLayMiddle}|${varLayBack}" />
<target xsi:type="Console"
name="logConsole"
layout="${varLayHeader}|${varLayMiddle}|${varLayBack}" />
</targets>
<rules>
<logger minlevel="Trace" name="*" writeTo="logFile" />
<logger minlevel="Trace" name="*" writeTo="logConsole" />
</rules>
</nlog>
参考链接