如何让 NLog 向目标注入依赖关系?

问题描述 投票:1回答:1

我有一个自定义的 NLog 日志目标类,它看起来像这样。

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 属性为空。

有没有更好的方法?比如说,能用的方法?

使用.NET Core 3、 NLog、Autofac。

c# .net-core dependency-injection autofac nlog
1个回答
1
投票

如果 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);
   }
}
© www.soinside.com 2019 - 2024. All rights reserved.