ASP.NET Core默认注入方式下如何注入多个实现(多种方式)

12 篇文章 2 订阅

在我们开发过程中,对于服务来说,一般我们定义interface实现均只存在一个具体实现(有人戏称这种情况为十代单传模式),这时候Core默认的注入方式已经支持我们的需求,但对于某些抽象定义实现来讲,我们可能会有多种具体实现,在项目中,我们可能会按照具体需求选用不同的实现。

首先先具体下我们的业务场景例子,假设我们有以下interface及它的两个具体实现

    public interface ILogicService
    {
        int GetNo();
    }

    public class LogicSericeImpt1 : ILogicService
    {
        public int GetNo()
        {
            return 1;
        }
    }
    public class LogicSericeImpt2 : ILogicService
    {
        public int GetNo()
        {
            return 2;
        }
    }

例子非常简单,就是不同的实现返回不同的编号,下面就来讲在注入的情况下怎么获取不同的实现。

直接注入IServiceProvider的方式


因为在Core里面,IServiceProvider是允许直接注入到具体应用里的,所以就有了直接通过IServiceProvider来获取具体实现的方式。

1. 通过GetService方式

首先注入具体实现

services.AddTransient<LogicSericeImpt1>();
services.AddTransient<LogicSericeImpt2>();

然后在构造函数中通过如下方式获取具体实现

public TodoController(IServiceProvider serviceProvider)
{
    var s1FromProvider = serviceProvider.GetService<LogicSericeImpt1>();
    var s2FromProvider = serviceProvider.GetService<LogicSericeImpt2>();
}

2. 通过GetServices方式

首先注入interface及具体实现

services.AddTransient<ILogicService, LogicSericeImpt1>();
services.AddTransient<ILogicService, LogicSericeImpt2>();

然后在构造函数中通过如下方式获取具体实现

public TodoController(IServiceProvider serviceProvider)
{
    var logicAllRegs = serviceProvider.GetServices<ILogicService>().ToList();
    var s1FromAllRegs = logicAllRegs[0];
    var s2FromAllRegs = logicAllRegs[1];
}

直接注入集合的方式


这种方式其实就是省去了注入IServiceProvider的过程,直接将GetServices获取的结果进行注入。首先注入interface及具体实现

services.AddTransient<ILogicService, LogicSericeImpt1>();
services.AddTransient<ILogicService, LogicSericeImpt2>();

然后在构造函数中通过如下方式获取具体实现

public TodoController(IEnumerable<ILogicService> services)
{
    var s1FromServices = services.First();
    var s2FromServices = services.Skip(1).First();
}

直接注入Func工厂的方式


在这种方式下,我们并不是直接注入具体实现,而是注入了Func这么一个工厂实现。首先我们还是需要注入具体实现

services.AddTransient<LogicSericeImpt1>();
services.AddTransient<LogicSericeImpt2>();

然后我们继续注入Func这个工厂,这里我们按int来返回不同的实现,当然你也可以采用其他方式比如string

services.AddSingleton(provider =>
{
    Func<int, ILogicService> func = n =>
    {
        switch (n)
        {
            case 1:
                return provider.GetService<LogicSericeImpt1>();
            case 2:
                return provider.GetService<LogicSericeImpt2>();
            default:
                throw new NotSupportedException();
        }
    };
    return func;
});

然后在构造函数中通过如下方式获取具体实现

public TodoController(Func<int, ILogicService> funcFactory)
{
    var s1FromFunc = funcFactory(1);
    var s2FromFunc = funcFactory(2);
}
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值