我有一个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模块来实现这一目标?如果我还没有找到任何具体的例子。任何帮助将不胜感激!
答案 0 :(得分:3)
覆盖模块的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())
});
}
}
在您的引导程序中注册此模块:
builder.RegisterModule(new AutofacLogInjectionModule());