I'm using NLog with this module:
public class LoggingModule : Autofac.Module
{
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
{
registration.Preparing += OnComponentPreparing;
registration.Activated += (sender, e) => InjectLoggerProperties(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) => IsLogger(p), (p, i) => GetLogger(t.FullName))
});
}
private static void InjectLoggerProperties(object instance)
{
var instanceType = instance.GetType();
var properties = instanceType
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => IsLogger(p) && p.CanWrite && p.GetIndexParameters().Length == 0);
foreach (var propToSet in properties)
{
propToSet.SetValue(instance, GetLogger(instanceType.FullName), null);
}
}
private static ILogger GetLogger(string name)
{
return LogManager.GetLogger(name);
}
private static bool IsLogger(ParameterInfo p)
{
return p.ParameterType == typeof (ILogger);
}
private static bool IsLogger(PropertyInfo p)
{
return p.PropertyType == typeof(ILogger);
}
}
Everything seems to work fine, except the logger's name is empty/wrong. On the first line of OnComponentPreparing
, the LimitType
is a Meta<Lazy<IAutofacActionFilter>>[]
instead of the expected LogControllerActionFilterAttribute
. How do I get the correct type name for the logger? In my logs, this is given as the logger name:
0, Culture=neutral, PublicKeyToken=b77a5c561934e089]][]
Edit:
This is a short and complete program demonstrating this issue. You'll need the module implementation above as well.
internal class Program
{
private static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterModule<LoggingModule>();
builder.RegisterType<Foo>().As<IFoo>();
var container = builder.Build();
// This prints out "0, Culture=neutral, PublicKeyToken=b77a5c561934e089]][]" for the logger name
foreach (var metalazyfoo in container.Resolve<Meta<Lazy<IFoo>>[]>())
metalazyfoo.Value.Value.Work(5);
// This prints out "Foo" for the logger name
container.Resolve<Meta<Lazy<IFoo>>>().Value.Value.Work(6);
Console.WriteLine("=== Done ===");
Console.ReadLine();
}
}
public class Foo : IFoo
{
private readonly Logger _logger;
public Foo(Logger logger)
{
_logger = logger;
}
public void Work(int x)
{
_logger.Debug(x);
}
}
public interface IFoo
{
void Work(int x);
}
Here LimitType should be
Instead of
This is to avoid creating loggers with the type of the activator, not the type of the underlying component being activated. Which is why you're getting the Meta>[] instead of LogControllerActionFilterAttribute.