我想使用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.");
}
}
}
[This Stackoverflow的答案表明,注入ILogger<T>
是一个坏主意,因为它太具体了。相反,答案是建议注入非通用基本类型ILogger
,该类型更简单,更易于测试且错误更少(我想主要是复制和粘贴错误)。
在上面的类中,我们想更改构造函数参数的数据类型:
public MyClass(ILogger logger)
{
_logger = logger;
}
然后,对于此类,我们需要某种方法将ILogger
解析为Logger<MyClass>
,或者对于任何类,在更一般的情况下,Logger<T>
都需要解析,其中T
代表要注入的类。
这是通过使用Simple Injector DI容器并有条件注册的Stackoverflow答案完成的:
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;
}
}
HTH。