繁体   English   中英

如何让 NLog 将依赖项注入目标?

[英]How can I get NLog to inject dependencies into a target?

我有一个自定义的 NLog 日志目标 class,如下所示:

public class MyTarget : AsyncTaskTarget
{
   public MyTarget() {}

   public MyTarget(INeedThisThingToFunction thing)
   {
      Thing = thing;
   }

   public INeedThisThingToFunction Thing { get; set; }

   public override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken cancellationToken)
   {
      Thing.Use();
      return null;
   }
}

我无法弄清楚如何确保调用第二个构造函数。 我在 Program.cs 中完成了这个:

public static void Main(string[] args)
{
   var host = CreateWebHostBuilder(args).Build();
   ConfigureLogging(host.Services.GetAutofacRoot());
   LogManager.GetCurrentClassLogger().Info("Hi mom");
   host.Run();
}

private static void ConfigureLogging(IComponentContext container) {
   ConfigurationItemFactory.Default.CreateInstance = type =>
   {
      if (type != typeof(MyTarget) return Activator.CreateInstance(type);
      var thing = new ThingTheTargetNeedsToFunction();
      return new MyTarget(thing);
   }
   LogManager.Configuration.Reload();
}

我也尝试了许多其他的事情,但这是最接近做某事的方法。 当调用LogManager.Configuration.Reload()时,会触发CreateInstance代码; 但是当Info方法触发时,目标上的Thing属性是 null。

有一个更好的方法吗? 像,一种有效的方式?

使用 .NET Core 3、NLog、Autofac。

如果Thing仅在构建host后可用,那么您可以这样做:

public static void Main(string[] args)
{   
   var host = CreateWebHostBuilder(args).UseNLog().Build();
   ConfigureLogging(host.Services.GetAutofacRoot());
   LogManager.GetCurrentClassLogger().Info("Hi mom");
   host.Run();
}

private static void ConfigureLogging(IComponentContext container)
{
   var defaultConstructor = ConfigurationItemFactory.Default.CreateInstance;
   ConfigurationItemFactory.Default.CreateInstance.CreateInstance = type =>
   {
      if (type == typeof(MyTarget))
      {
          var thing = new ThingTheTargetNeedsToFunction();
          return new MyTarget(thing);
      }

      return defaultConstructor(type);
   };

   // Reload config and assign the newly reloaded config
   LogManager.Configuration = LogManager.Configuration?.Reload();
}

然后确保您的自定义MyTarget可以处理它在未分配Thing的“禁用模式”下运行:

[Target("MyTarget")] 
public class MyTarget : AsyncTaskTarget
{
   public MyTarget() {}

   public MyTarget(INeedThisThingToFunction thing)
   {
      Thing = thing;
   }

   public INeedThisThingToFunction Thing { get; set; }

   public override await Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken cancellationToken)
   {
      if (Thing == null)
         return null; // Handle that `Thing` is unassigned by default-constructor

      await Thing.UseAsync().ConfigureAwait(false);
   }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM