Asp.NET Core 一个接口的多个实现如何通过 DI 注册?

咨询区

  • LP13

我有三个 Service 类实现了同一个接口,参考代码如下:

public interface IService { }
public class ServiceA : IService { }
public class ServiceB : IService { } 
public class ServiceC : IService { }

我知道像其他的 DI 容器,比如 Unity 是在注册实现类的时候通过不同的key来区分,在 ASP.NET Core 中做 AddService 时并没有看到 keyname 参数的重载方法。

public void ConfigureServices(IServiceCollection services)
    {            
         // How do I register services of the same interface?            
    }


    public MyController:Controller
    {
       public void DoSomething(string key)
       { 
          // How do I resolve the service by key?
       }
    }

请问我该如何实现呢?

回答区

  • Miguel A. Arilla

我也遇到了这种场景,不过我是用 Func 做了一个折中方案。

首先:定义一个 委托

public delegate IService ServiceResolver(string key);

然后:在 Startup.cs 中做多个实现类注册。

services.AddTransient<ServiceA>();
services.AddTransient<ServiceB>();
services.AddTransient<ServiceC>();

services.AddTransient<ServiceResolver>(serviceProvider => key =>
{
    switch (key)
    {
        case "A":
            return serviceProvider.GetService<ServiceA>();
        case "B":
            return serviceProvider.GetService<ServiceB>();
        case "C":
            return serviceProvider.GetService<ServiceC>();
        default:
            throw new KeyNotFoundException(); // or maybe return null, up to you
    }
});

后期:如果想使用的话,通过 key 从 Func 中提取具体的实例,参考代码如下:

public class Consumer
{
    private readonly IService _aService;

    public Consumer(ServiceResolver serviceAccessor)
    {
        _aService = serviceAccessor("A");
    }

    public void UseServiceA()
    {
        _aService.DoTheThing();
    }
}

为了做演示目的,我这里只用了 string 作为解析,你可以根据自己的场景具体实现。

点评区

Asp.Net Core 中是不支持这种多注册的,这就有点尴尬了,Miguel A. Arilla 大佬提供的方案不错,学习了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值