我想使用 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;
}
}
呵呵。