How to inject NLog using Autofac in ASP.NET Webforms

别说谁变了你拦得住时间么 提交于 2019-12-11 03:22:16

问题


I have an ASP.NET Webforms project that I've been recently converting to use Dependency Injection via Autofac. It has all been going well, that is until I tried to inject my NLog instances. I can't work out how to perform the equivalent of the static GetCurrentClassLogger() method calls with the property injected Logger object.

Here is my sample code illustrating the problem:

Global.asax.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using Autofac;
using Autofac.Integration.Web;

public class Global : HttpApplication, IContainerProviderAccessor
{
  private static IContainerProvider containerProvider;

  public IContainerProvider ContainerProvider
  {
    get { return containerProvider; }
  }

  void Application_Start(object sender, EventArgs e)
  {
    var builder = new ContainerBuilder();
    Bootstrapper.RegisterInstances(builder);
    containerProvider = new ContainerProvider(builder.Build());
  }
}

Bootstrapper.cs

using Autofac;

public static class Bootstrapper
{
  public static void RegisterInstances(ContainerBuilder builder)
  {
    builder.RegisterType<Logger>().As<ILogger>().InstancePerRequest();
    builder.RegisterType<MyTestModule>().As<IMyTestModule>().InstancePerRequest();
  }
}

MyTestModule.cs

using System;

public class MyTestModule : IMyTestModule
{
   // was previously: protected static readonly ILogger Logger = LogManager.GetCurrentClassLogger();

  private ILogger _logger;

  public MyTestModule(ILogger logger)
  {
    _logger = logger;
  }

  public void DoSomethingBad()
  {
    try
    {
        int z = 5 / 0;
    }
    catch (Exception ex)
    {
        _logger.Error("Error!", ex);
    }
  }
}

public interface IMyTestModule
{
  void DoSomethingBad();
}

PageBase.cs

public abstract class PageBase : Page
{
  // was previously: protected static readonly ILogger Logger = LogManager.GetCurrentClassLogger();

  public ILogger Logger { get; set; }

  public IMyTestModule MyTestModuleInstance { get; set; }
}

Default.aspx

<%@ Page Title="Home" Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<html>
  <head></head>
  <body></body>
</html>

Default.aspx.cs

using System;

public partial class _Default : PageBase
{
  protected void Page_Load(object sender, EventArgs e)
  {
    MyTestModuleInstance.DoSomethingBad();
  }
}

You can see in PageBase.cs and MyTestModule.cs I have commented out the previous static calls to create the NLog instance:

protected static readonly ILogger Logger = LogManager.GetCurrentClassLogger();

They are now simply replaced with the Autofac dependency injected property like this:

public ILogger Logger { get; set; }

This works in so much that the Logger object gets initialised to an instance of the logger.

How do I perform the equivalent of LogManager.GetCurrentClassLogger() ?

Is there something I need to do with NLog modules to achieve this? If there is I've not been able to find any specific examples. Any help would be much appreciated!


回答1:


Override the AttachTocomponentRegistaration of your Module:

public class AutofacLogInjectionModule : Module
{
    protected override void AttachToComponentRegistration(IComponentRegistry registry, IComponentRegistration registration)
    {
        registration.Preparing += OnComponentPreparing;
    }

    static void OnComponentPreparing(object sender, PreparingEventArgs e)
    {
        e.Parameters = e.Parameters.Union(new[]
    {
        new ResolvedParameter((p, i) => p.ParameterType == typeof(ILogger), (p, i) => LogManager.GetCurrentClassLogger())
    });
    }

}

And Register this module in your bootstrap:

builder.RegisterModule(new AutofacLogInjectionModule());


来源:https://stackoverflow.com/questions/28443955/how-to-inject-nlog-using-autofac-in-asp-net-webforms

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!