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

问题描述 投票:1回答:1

我想使用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是要注入的类)?

.net dependency-injection unity-container
1个回答
1
投票

您可以为每个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。

© www.soinside.com 2019 - 2024. All rights reserved.