I have question about Autofac : How can I get name of class which request instance from container?
Is it possible to get name of the class "Autofac_Test" passed into constructor by autofac when object is created?
My code:
using System;
using System.Diagnostics;
using System.Reflection;
using Autofac;
using Xunit;
public class BootStrap
{
public IContainer Configure()
{
var builder = new ContainerBuilder();
builder.Register(b => new MyLogger(MethodBase.GetCurrentMethod().ReflectedType)).As<ILog>();
return builder.Build();
}
}
public class Autofac_Test
{
private IContainer _containter;
public Autofac_Test()
{
_containter = new BootStrap().Configure();
}
[Fact]
public void Should_create_class_with_Name_BlaBla()
{
var logger = _containter.Resolve<ILog>();
Assert.True(logger.Name == "Autofac_Test");
}
}
public class MyLogger : ILog
{
public string Name { get; private set; }
public MyLogger(Type name)
{
Name = name.FullName;
}
public void Info(string message)
{
Debug.WriteLine(string.Format("{0} {1}", Name, message));
}
}
public interface ILog
{
void Info(string message);
string Name { get; }
}
For your specific case it will be quite difficult to obtain this information. But as I understand the question, MyLogger
need to know the type name where it will be injected and the code sample may not be relevant.
In this case you can use a module and the Preparing event :
public class LoggingModule : Autofac.Module
{
protected override void AttachToComponentRegistration(
IComponentRegistry componentRegistry, IComponentRegistration registration)
{
registration.Preparing += (sender, e) =>
{
Type limitType = e.Component.Activator.LimitType;
e.Parameters = e.Parameters.Union(new[] {
new ResolvedParameter((pi, c) => pi.ParameterType == typeof(ILogger),
(pi, c) => c.Resolve<ILogger>(new NamedParameter("name", limitType.Name))),
});
};
}
}
Then you will have to register your module like this :
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterModule<LoggingModule>();
builder.RegisterType<MyLogger>().As<ILogger>();
Now each time a ILogger
will be injected to a type it will have the correct name.
class Foo
{
public Foo(ILogger logger)
{
this._loggerName = logger.Name;
}
private readonly String _loggerName;
public String LoggerName
{
get
{
return this._loggerName;
}
}
}
LoggerName
will be Foo
.
Your test can now look like this :
[Fact]
public void Should_create_class_with_Name_BlaBla()
{
var foo = _containter.Resolve<Foo>();
Assert.AreEquals("foo", foo.LoggerName, "invalid loggerName");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With