在构造函数注入期间,Unity DI 容器能否识别正在构造的类型,并在解析引用时使用它?



我想使用 Unity DI 容器将Microsoft.Extensions.Logging记录器注入到类的构造函数中:

using Microsoft.Extensions.Logging;
namespace LoggingExample
{    
public class MyClass
{
private readonly ILogger<MyClass> _logger;
public MyClass(ILogger<MyClass> logger)
{
_logger = logger;
}
public void DoSomething()
{
_logger.LogInformation("Doing something.");
}
}
}

这个 Stackoverflow 答案表明注入ILogger<T>是一个坏主意,因为它太具体了。 相反,答案建议注入非泛型基本类型ILogger,它更简单,更容易测试且不易出错(我猜主要是复制和粘贴错误)。

在上面的类中,我们希望更改构造函数参数的数据类型:

public MyClass(ILogger logger)
{
_logger = logger;
}

然后,我们需要某种方法将ILogger解析为此类的Logger<MyClass>,或者在更一般的情况下Logger<T>任何类,其中T表示要注入的类。

这是在Stackoverflow答案中使用简单注入器DI容器和条件注册完成的:

container.RegisterConditional(
typeof(ILogger),
c => typeof(Logger<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
_ => true);

是否可以在 Unity 中进行有条件注册? Unity 是否有其他方法可以识别它注入ILogger的类并解析引用以注入Logger<T>对象(T类被注入到其中)?

您可以为每个ILogger实例定义一个名称,并使用[Dependency]属性指定所需的名称。例:

public static class Constants
{
public const string LOGGER_MYCLASS_UNITY_KEY = "ILogger<MyClass>";
}

在 Unity 注册中:

IUnityContainer container = new UnityContainer();
container.RegisterType<ILogger, Logger<MyClass>>(Constants.LOGGER_MYCLASS_UNITY_KEY, 
new ContainerControllerLifetimeManager());

在需要记录器的类的构造函数中:

public class MyClass
{
private readonly ILogger<MyClass> _logger;
public MyClass([Dependency(Constants.LOGGER_MYCLASS_UNITY_KEY)] ILogger logger)
{
_logger = (ILogger<MyClass>)logger;
}
}

呵呵。

最新更新