.NetCore WPF应用Nlog日志模块

当借助CommunityToolkit.Mvvm工具来开发WPF,

通过官方示例可见,IOC提供了很大的便利,可以将服务接口,ViewModel放到容器

public sealed partial class App : Application
{
    public App()
    {
        Services = ConfigureServices();

        this.InitializeComponent();
    }

    /// <summary>
    /// Gets the current <see cref="App"/> instance in use
    /// </summary>
    public new static App Current => (App)Application.Current;

    /// <summary>
    /// Gets the <see cref="IServiceProvider"/> instance to resolve application services.
    /// </summary>
    public IServiceProvider Services { get; }

    /// <summary>
    /// Configures the services for the application.
    /// </summary>
    private static IServiceProvider ConfigureServices()
    {
        var services = new ServiceCollection();

        services.AddSingleton<IFilesService, FilesService>();
        services.AddSingleton<ISettingsService, SettingsService>();
        services.AddSingleton<IClipboardService, ClipboardService>();
        services.AddSingleton<IShareService, ShareService>();
        services.AddSingleton<IEmailService, EmailService>();

        return services.BuildServiceProvider();
    }
}

在ConfigureServices方法中,可以将本文我们将要用到的Nlog模块引入系统中,从Nlog官网去找方法:

先把依赖包引用好。。。

1:代码配置

var config = new NLog.Config.LoggingConfiguration();

// Targets where to log to: File and Console
var logfile = new NLog.Targets.FileTarget("logfile") { FileName = "file.txt" };
var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
            
// Rules for mapping loggers to targets            
config.AddRule(LogLevel.Info, LogLevel.Fatal, logconsole);
config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile);
            
// Apply config           
NLog.LogManager.Configuration = config;

NLog 5.0可以这样写:

NLog.LogManager.Setup().LoadConfiguration(builder => {
   builder.ForLogger().FilterMinLevel(LogLevel.Info).WriteToConsole();
   builder.ForLogger().FilterMinLevel(LogLevel.Debug).WriteToFile(fileName: "file.txt");
});

2:appsettings.json配置

前提是:你的程序是ASP.NET Core或.NET Core应用程序,并且要使用

NLog.Extensions.Logging 或 NLog.Web.AspNetCore

NLog.Extensions.Logging现在可以使用Microsoft Extension ConfigurationSection从appsettings.json加载NLog的配置,代码示例:

方式a:

注意代码:NLog.LogManager.Configuration = new NLogLoggingConfiguration(config.GetSection("NLog"));

var config = new ConfigurationBuilder()
   .SetBasePath(System.IO.Directory.GetCurrentDirectory())
   .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
   .Build();

NLog.LogManager.Configuration = new NLogLoggingConfiguration(config.GetSection("NLog"));

也可以这样:

方式b:

注意代码:.LoadConfigurationFromAppSettings()

Fluent API added with NLog.Web.AspNetCore ver. 4.9.3

Supports appsettings.json override by loading environment specific settings based on ASPNETCORE_ENVIRONMENT:

var logger = LogManager.Setup()
                       .LoadConfigurationFromAppSettings()
                       .GetCurrentClassLogger();

也可以这样:

方式c:

无需config.GetSection("NLog"),LoadConfigurationFromSection(config)会自动匹配Nlog配置的json字符串。

注意代码:.LoadConfigurationFromSection(config)

Manual loading of appsettings.json with fluent API:

var config = new ConfigurationBuilder()
                .SetBasePath(basePath ?? Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{environment}.json", optional: true)
                .AddEnvironmentVariables().Build();
var logger = LogManager.Setup()
                       .LoadConfigurationFromSection(config)
                       .GetCurrentClassLogger();

仔细看上面几种方式,可以知道,无论如何,你都要对配置文件进行加载,标红的注意代码,如果没有对配置文件加载,当然是不生效的。

3:nlog.config配置:

官方介绍有说到,Nlog会自动去加载配置文件,但有时平台需要显式的进行加载,代码示例:

NLog.LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration("nlog.config");

NLog v5引入了这种流畅的扩展方法:

NLog.LogManager.Setup().LoadConfigurationFromAssemblyResource(typeof(App).GetTypeInfo().Assembly);

更多的加载方式,官方都有说明,这里先介绍到此。

那么以上都是讲配置,如何在.net6的WPF项目中使用呢?

以下是官方的一段示例代码,我们从中去分析:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Extensions.Logging;

static void Main(string[] args)
{
   var logger = LogManager.GetCurrentClassLogger();
   try
   {
      var config = new ConfigurationBuilder()
         .SetBasePath(System.IO.Directory.GetCurrentDirectory()) //From NuGet Package Microsoft.Extensions.Configuration.Json
         .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
         .Build();

      using var servicesProvider = new ServiceCollection()
          .AddTransient<Runner>() // Runner is the custom class
          .AddLogging(loggingBuilder =>
          {
            // configure Logging with NLog
            loggingBuilder.ClearProviders();
            loggingBuilder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
            loggingBuilder.AddNLog(config);
          }).BuildServiceProvider();

      var runner = servicesProvider.GetRequiredService<Runner>();
      runner.DoAction("Action1");

      Console.WriteLine("Press ANY key to exit");
      Console.ReadKey();
   }
   catch (Exception ex)
   {
      // NLog: catch any exception and log it.
      logger.Error(ex, "Stopped program because of exception");
      throw;
   }
   finally
   {
      // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
      LogManager.Shutdown();
   }
}

ServiceCollection类,我们就从这里入手,这个类刚好与文章开头的CommunityToolkit.Mvvm示例代码相符合,它便是我们配置应用程序服务的入口,因此可以这样将NLog服务注入:

services.AddLogging(builder =>
            {
                builder.ClearProviders();
                builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
                builder.AddNLog(config.GetSection("NLog"));//也可以直接丢config进来,NLog会自动根据关键字"NLog"进行解析
            });

之后,我们就可以在任意类中通过DI的方式使用nlog输入日志了。

比如:

 public class Runner
 {
     private readonly ILogger<Runner> _logger;

     public Runner(ILogger<Runner> logger)
     {
         _logger = logger;
     }

     public void DoAction(string name)
     {
         _logger.LogDebug(20, "Doing hard work! {Action}", name);
     }
 }

至此,本文可以结束了。但我还想再说一点,以上是使用了 Microsoft Logging with Dependency Injection的方式,如果是想将一个logger服务对象放到某个IOC容器里如何做呢?

本文使用的IOC是CommunityToolkit.Mvvm.DependencyInjection.IOC

我们可以在配置ISericeCollection的时候,创建一个logger对象,同时从配置文件初始化Nlog对象,代码示例:

var loggerFactory = LoggerFactory.Create(builder => builder.AddNLog(configuration));
            var logger = loggerFactory.CreateLogger("XXX任意名字,也可为空");
            services.AddSingleton(logger);//将对象在容器中注册为单例

之后,我们就可以在任意类中,从IOC容器中使用该logger服务了,并且同样支持构造函数注入方式,比如:

注意:我们注册的是Microsoft.Extensions.Logging.ILogger,非NLog.ILogger

 public class Runner
    {
        private readonly Microsoft.Extensions.Logging.ILogger _logger;

        public Runner()
        {
            _logger = Ioc.Default.GetService<ILogger>();
        }

        public void DoAction(string name)
        {
            _logger.LogDebug(20, "Doing hard work! {Action}", name);
        }
    }

然后创建一个扩展方法:

 public static void AddNlogService(this IServiceCollection services, IConfiguration configuration)
        {
            var loggerFactory = LoggerFactory.Create(builder => builder.AddNLog(configuration));
            var logger = loggerFactory.CreateLogger("XXX任意名字,也可为空");
            services.AddSingleton(logger);//方式1

            //这两种方式用一个就可以了
            services.AddLogging(builder =>
            {
                builder.ClearProviders();
                builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
                builder.AddNLog(config);
            });//方式2
        }

最初的配置服务代码,再这么改一下,就大功告成了!

 /// <summary>
    /// Configures the services for the application.
    /// </summary>
    private static IServiceProvider ConfigureServices()
    {
        var services = new ServiceCollection();
        var appConfig = new ConfigurationBuilder()
           .SetBasePath(System.IO.Directory.GetCurrentDirectory()) //From NuGet Package Microsoft.Extensions.Configuration.Json
           .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
           .Build();
        services.AddSingleton<IFilesService, FilesService>();
        services.AddNlogSetup(appConfig);//添加日志服务

        return services.BuildServiceProvider();
    }

参考:

Configure from code · NLog/NLog Wiki · GitHub

NLog configuration with appsettings.json · NLog/NLog.Extensions.Logging Wiki · GitHub

Explicit NLog configuration loading · NLog/NLog Wiki · GitHub

Configuration file · NLog/NLog Wiki · GitHub

NLog GetCurrentClassLogger and Microsoft ILogger · NLog/NLog.Extensions.Logging Wiki · GitHub

https://learn.microsoft.com/zh-cn/dotnet/communitytoolkit/mvvm/ioc

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Boogaloo-Jer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值