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

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/starfd/article/details/81282651

在我们开发过程中,对于服务来说,一般我们定义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);
}
展开阅读全文

没有更多推荐了,返回首页