如何在 ASP.NET Webforms 中使用 Autofac 注入 NLog
How to inject NLog using Autofac in ASP.NET Webforms
我有一个 ASP.NET Webforms 项目,我最近将其转换为通过 Autofac 使用依赖注入。一切进展顺利,直到我尝试注入我的 NLog 实例。我不知道如何使用 属性 注入的 Logger 对象执行静态 GetCurrentClassLogger() 方法调用的等效方法。
这是说明问题的示例代码:
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();
}
}
可以看到在PageBase.cs和MyTestModule.cs我已经注释掉了之前静态调用创建NLog 实例:
protected static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
它们现在简单地替换为注入的 Autofac 依赖项 属性,如下所示:
public ILogger Logger { get; set; }
这非常有效,以至于 Logger 对象被初始化为记录器的一个实例。
我如何执行相当于 LogManager.GetCurrentClassLogger() 的操作?
我需要对 NLog 模块做些什么才能实现这个目标吗?如果有的话,我找不到任何具体的例子。任何帮助将不胜感激!
覆盖模块的 AttachTocomponentRegistaration:
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())
});
}
}
并在您的 bootstrap 中注册此模块:
builder.RegisterModule(new AutofacLogInjectionModule());
我有一个 ASP.NET Webforms 项目,我最近将其转换为通过 Autofac 使用依赖注入。一切进展顺利,直到我尝试注入我的 NLog 实例。我不知道如何使用 属性 注入的 Logger 对象执行静态 GetCurrentClassLogger() 方法调用的等效方法。
这是说明问题的示例代码:
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();
}
}
可以看到在PageBase.cs和MyTestModule.cs我已经注释掉了之前静态调用创建NLog 实例:
protected static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
它们现在简单地替换为注入的 Autofac 依赖项 属性,如下所示:
public ILogger Logger { get; set; }
这非常有效,以至于 Logger 对象被初始化为记录器的一个实例。
我如何执行相当于 LogManager.GetCurrentClassLogger() 的操作?
我需要对 NLog 模块做些什么才能实现这个目标吗?如果有的话,我找不到任何具体的例子。任何帮助将不胜感激!
覆盖模块的 AttachTocomponentRegistaration:
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())
});
}
}
并在您的 bootstrap 中注册此模块:
builder.RegisterModule(new AutofacLogInjectionModule());