C# Autofac-如何在创建实例时获取类名

C# Autofac-如何在创建实例时获取类名,c#,dependency-injection,inversion-of-control,autofac,ioc-container,C#,Dependency Injection,Inversion Of Control,Autofac,Ioc Container,我对Autofac有疑问: 如何从容器中获取请求实例的类的名称 在创建对象时,是否可以获得Autofac传递到构造函数中的类“Autofac_Test”的名称 我的代码: using System; using System.Diagnostics; using System.Reflection; using Autofac; using Xunit; public class BootStrap { public IContainer Configure() {

我对Autofac有疑问: 如何从容器中获取请求实例的类的名称

在创建对象时,是否可以获得Autofac传递到构造函数中的类“Autofac_Test”的名称

我的代码:

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; }
}
使用系统;
使用系统诊断;
运用系统反思;
使用Autofac;
使用Xunit;
公共类引导
{
公共IContainer配置()
{
var builder=new ContainerBuilder();
Register(b=>newmylogger(MethodBase.GetCurrentMethod().ReflectedType)).As();
返回builder.Build();
}
}
公共类Autofac_测试
{
私人集装箱;
公共Autofac_测试()
{
_containter=new BootStrap().Configure();
}
[事实]
public void应创建带有名称的类
{
变量记录器=_containter.Resolve();
Assert.True(logger.Name==“Autofac_Test”);
}
}
公共类MyLogger:ILog
{
公共字符串名称{get;private set;}
公共MyLogger(类型名称)
{
Name=Name.FullName;
}
公共无效信息(字符串消息)
{
Debug.WriteLine(string.Format(“{0}{1}”,名称,消息));
}
}
公共接口ILog
{
无效信息(字符串消息);
字符串名称{get;}
}
更新

@西里尔·杜兰德已经证明这是可能的。下面的建议仍然正确,但不是很好

看起来autofac不支持您想要的功能。当然,您可以在MyLogger构造函数中解析调用堆栈,但这会降低性能

已经有一个关于非常相似的事情的问题了,建议改为使用工厂


对于您的具体情况,很难获得此信息。但据我所知,
MyLogger
需要知道它将被注入的类型名,代码示例可能不相关

在这种情况下,您可以使用模块和准备事件:

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))),
            });
        };
    }
}
LoggerName
将是
Foo

您的测试现在可以如下所示:

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterModule<LoggingModule>();
builder.RegisterType<MyLogger>().As<ILogger>();
[Fact]
public void Should_create_class_with_Name_BlaBla()
{
    var foo = _containter.Resolve<Foo>();
    Assert.AreEquals("foo", foo.LoggerName, "invalid loggerName");
}
[事实]
public void应创建带有名称的类
{
var foo=_containter.Resolve();
Assert.arequals(“foo”,foo.LoggerName,“无效LoggerName”);
}

你不能/不想考虑解决一些IGOGPROSTORT,或者手动提供这个类型作为参数(既然你在这里使用服务定位器)?也许,我应该像你所说的那样考虑…谢谢你的帮助…谢谢你的帮助,但是你的代码不起作用。可能我太累了。in方法:void AttachToComponentRegistration(…我得到了异常:Autofac.Core.DependencySolutionException:调用类型“MyLogger”上的构造函数“void.ctor(System.Type)”时引发了异常。-->无法强制转换类型为“System.String”Type“System.Type”的对象。(有关详细信息,请参阅内部异常。)这是由
新的NamedParameter(“name”,limitType.name))
引起的。您的
MyLogger
需要类型为
type
的参数
name
。我的代码没有类型名称,而不是类型本身。将构造函数更改为接受字符串或将行更改为
newnamedParameter(“name”,limitType))
Ok,但仍然存在问题,因为它返回类名“Foo”,而我需要请求对象的类名(在本例中为“Autofac_Test”),我认为您的测试是错误的,并且您没有测试应用程序使用的内容。记录器通常需要知道它被注入的类,这就是代码所做的。在测试中,您不需要注入
ILogger
,只需要解析它。应用程序不应该解析它,而应该使用注入。我修改了测试,在Foo中注入ILogger,并检查
Foo中注入的
ILogger
是否知道它被注入的位置。
[Fact]
public void Should_create_class_with_Name_BlaBla()
{
    var foo = _containter.Resolve<Foo>();
    Assert.AreEquals("foo", foo.LoggerName, "invalid loggerName");
}