问题
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