Skip to content

Instantly share code, notes, and snippets.

@jayharris
Created January 28, 2013 08:21
Show Gist options
  • Save jayharris/4653868 to your computer and use it in GitHub Desktop.
Save jayharris/4653868 to your computer and use it in GitHub Desktop.
Autofac Module to inject log4net ILog properties with type-specific Logs.
public class LogInjectionModule : Module {
protected override void AttachToComponentRegistration(IComponentRegistry registry,
IComponentRegistration registration) {
registration.Preparing += OnComponentPreparing;
var implementationType = registration.Activator.LimitType;
var injectors = BuildInjectors(implementationType).ToArray();
if (!injectors.Any()) {
return;
}
registration.Activated += (s, e) => {
foreach (var injector in injectors) {
injector(e.Context, e.Instance);
}
};
}
private static void OnComponentPreparing(object sender, PreparingEventArgs e) {
var t = e.Component.Activator.LimitType;
e.Parameters =
e.Parameters.Union(new[]
{new ResolvedParameter((p, i) => p.ParameterType == typeof (ILog), (p, i) => LogManager.GetLogger(t))});
}
private static IEnumerable<Action<IComponentContext, object>> BuildInjectors(Type componentType) {
var properties =
componentType.GetProperties(BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.PropertyType == typeof(ILog) && !p.GetIndexParameters().Any())
.Where(p =>
{
var accessors = p.GetAccessors(false);
return accessors.Length != -1 || accessors[0].ReturnType == typeof(void);
});
foreach (var propertyInfo in properties)
{
var propInfo = propertyInfo;
yield return (context, instance) => propInfo.SetValue(instance, LogManager.GetLogger(componentType), null);
}
}
}
@piers7
Copy link

piers7 commented May 5, 2015

My experience has been that it should be 'e.Component.Target.Activator.LimitType', to avoid creating loggers with the type of the activator, not the type of the underlying component being activated.
With the gist above, if the dependency is on - say - Func<Owned>, then that's the type that gets passed to LogManager.GetLogger(), rather than (as expected) T.
(The autofac doco is also wrong)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment