0x01 前言

.NET Core Microsoft依赖注入(DI)非常有用,但是如何处理具有多种实现的接口? 运行时可以基于配置选择这些实现之一吗? 可以反射实现吗?

0x02 一个接口实现2个类

接口定义:

public interface IHelloer
{
    string SayHello();
}

具体实现:

public class HelloerA : IHelloer
{
    public string SayHello()
    {
        return $"Hello from {nameof(HelloerA)}";
    }
}

public class HelloerB : IHelloer
{
    public string SayHello()
    {
        return $"Hello from {nameof(HelloerB)}";
    }
}

依赖注入:

将HelloerA和HelloerB都注册到DI容器中。

 services.AddTransient<IHelloer, HelloerA>();
 services.AddTransient<IHelloer, HelloerB>();

 

刚才我们注册了同一接口的两组实现,那么.Net Core运行时将选择哪种实现?

完整代码:

class Program
    {
        static void Main(string[] args)
        {
            IServiceCollection services = new ServiceCollection();
            services.AddTransient<IHelloer, HelloerA>();
            services.AddTransient<IHelloer, HelloerB>();
            var builder = services.BuildServiceProvider();

            var message = builder.GetRequiredService<IHelloer>();
            Console.WriteLine(message.SayHello());
        }
    }

Ctrl+F5 执行后,控制台上会输出:

Hello from HelloerB

.NET Core中具有多个实现的依赖注入实现

 

 如上图:结果是HelloerB,这是我们在DI容器中注册的最后一项。 问题来了,如果我想在运行时使用HelloerA,该怎么办?

 

实际上,在.NET Core中,当您为一个接口注册多个实现时,可以向构造函数注入该接口的集合,即所有已注册的实现。

 class Program
    {
        static void Main(string[] args)
        {
            IServiceCollection services = new ServiceCollection();
            services.AddTransient<IHelloer, HelloerA>();
            services.AddTransient<IHelloer, HelloerB>();
            var builder = services.BuildServiceProvider();

            var message = builder.GetRequiredService<IEnumerable<IHelloer>>();
            Console.WriteLine(message.First().SayHello());
        }
    }

 

执行结果

.NET Core中具有多个实现的依赖注入实现

 

当然在项目中,我们绝对不能编写这样的硬代码,我们希望通过配置文件选择特定的实现

 

相关文章:

  • 2022-03-05
  • 2022-12-23
  • 2021-04-21
  • 2022-12-23
  • 2021-08-15
  • 2021-07-12
  • 2021-12-22
猜你喜欢
  • 2022-12-23
  • 2021-07-12
  • 2022-12-23
  • 2022-02-14
  • 2021-12-07
  • 2022-12-23
  • 2023-02-26
相关资源
相似解决方案