-
-
Save SLaks/3932087 to your computer and use it in GitHub Desktop.
Faster Log4Net and NLog modules for Autofac
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using Autofac; | |
using Autofac.Core; | |
using NLog; | |
using log4net; | |
using LogManager = NLog.LogManager; | |
namespace AutofacIdea | |
{ | |
public class NLogModule : LogModule<Logger> | |
{ | |
protected override Logger CreateLoggerFor(Type type) | |
{ | |
return LogManager.GetLogger(type.FullName); | |
} | |
} | |
public class Log4NetModule : LogModule<ILog> | |
{ | |
protected override ILog CreateLoggerFor(Type type) | |
{ | |
return log4net.LogManager.GetLogger(type.FullName); | |
} | |
} | |
public abstract class LogModule<TLogger> : Autofac.Module { | |
protected abstract TLogger CreateLoggerFor(Type type); | |
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration) { | |
var type = registration.Activator.LimitType; | |
if (HasConstructorDependencyOnLogger(type)) | |
registration.Preparing += InjectLoggerViaConstructor; | |
var properties = GetLoggerProperties(type).ToList(); | |
if (properties.Count > 0) { | |
registration.Activated += (s, e) => { | |
var logger = CreateLoggerFor(type); | |
foreach (var prop in properties) { | |
prop.SetValue(e.Instance, logger, BindingFlags.SetProperty | BindingFlags.Instance, null, null, null); | |
} | |
}; | |
} | |
} | |
private IEnumerable<PropertyInfo> GetLoggerProperties(Type type) { | |
return type.GetProperties().Where(property => property.CanWrite && property.PropertyType == typeof(TLogger)); | |
} | |
private bool HasConstructorDependencyOnLogger(Type type) { | |
return type.GetConstructors() | |
.Any(ctor => ctor.GetParameters() | |
.Any(parameter => parameter.ParameterType == typeof(TLogger))); | |
} | |
private void InjectLoggerViaConstructor(object sender, PreparingEventArgs e) { | |
e.Parameters = e.Parameters.Concat(Enumerable.Repeat( | |
new ResolvedParameter((parameter, context) => parameter.ParameterType == typeof(TLogger), (p, i) => CreateLoggerFor(p.Member.DeclaringType)) | |
, 1)); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Autofac; | |
using Microsoft.VisualStudio.TestTools.UnitTesting; | |
using NLog; | |
namespace AutofacIdea | |
{ | |
[TestClass] | |
public class LogModuleTests | |
{ | |
[TestMethod] | |
public void ShouldInjectLoggerViaConstructor() | |
{ | |
var builder = new ContainerBuilder(); | |
builder.RegisterModule<NLogModule>(); | |
builder.RegisterType<ClassWithLoggerInjectedViaConstructor>().AsSelf(); | |
var container = builder.Build(); | |
var instance = container.Resolve<ClassWithLoggerInjectedViaConstructor>(); | |
Assert.IsNotNull(instance.Logger); | |
} | |
[TestMethod] | |
public void ShouldInjectLoggerViaProperty() | |
{ | |
var builder = new ContainerBuilder(); | |
builder.RegisterModule<NLogModule>(); | |
builder.RegisterType<ClassWithLoggerInjectedViaProperty>().AsSelf().PropertiesAutowired(); | |
var container = builder.Build(); | |
var instance = container.Resolve<ClassWithLoggerInjectedViaProperty>(); | |
Assert.IsNotNull(instance.Logger); | |
} | |
public class ClassWithLoggerInjectedViaConstructor | |
{ | |
public Logger Logger { get; private set; } | |
public ClassWithLoggerInjectedViaConstructor(Logger logger) | |
{ | |
Logger = logger; | |
} | |
} | |
public class ClassWithLoggerInjectedViaProperty | |
{ | |
public Logger Logger { get; set; } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment