C# .Net核心服务容器,是否保证为接口注册最后一个服务? 问题:

C# .Net核心服务容器,是否保证为接口注册最后一个服务? 问题:,c#,asp.net-core-mvc,.net-core,ioc-container,C#,Asp.net Core Mvc,.net Core,Ioc Container,使用默认的Asp.net核心IoC容器,我是否可以保证,如果为一个接口注册了多个对象类型,并且我请求为该接口提供服务,IoC将始终返回为该接口注册的最后一个对象类型 (我通读了.Net核心依赖项注入文档,它似乎没有解决这个问题。) 示范 假设我有这个界面: interface ITest { void Create(int id); } 这些课程: public class TestOne: ITest { int id; public void Create(int

使用默认的Asp.net核心IoC容器,我是否可以保证,如果为一个接口注册了多个对象类型,并且我请求为该接口提供服务,IoC将始终返回为该接口注册的最后一个对象类型

(我通读了.Net核心依赖项注入文档,它似乎没有解决这个问题。)

示范 假设我有这个界面:

interface ITest
{

    void Create(int id);
}
这些课程:

public class TestOne: ITest {
    int id;
    public void Create(int id) {
        this.id = id;
    }
}

public class TestTwo: ITest {
    int id;
    public void Create(int id) {
        this.id = id;
    }
}


public class TestThree: ITest {
    int id;
    public void Create(int id) {
        this.id = id;
    }
}
现在在
ConfigureServices
方法的Startup.cs中,我添加了以下代码:

services.AddSingleton<ITest, TestTwo>();
services.AddSingleton<ITest, TestThree>();
services.AddSingleton<ITest, TestOne>();
 var serviceCollection = app.ApplicationServices.GetServices<ITest>();
我得到了一组对象:
TestTwo
TestThree
TestOne
,按顺序排列

在startup.cs
Configure
方法中,如果我编写此代码:

var service = app.ApplicationServices.GetService<ITest>();
var service=app.ApplicationServices.GetService();
它似乎总是返回为接口注册的最后一个对象的实例,在本例中为
TestOne


我是否可以保证,如果为一个接口注册了多个对象类型,并且我要求为该接口提供服务,IoC将始终返回为该接口注册的最后一个对象类型?

我想说,获得最后一个对象类型是有保证的。如果查看,可以看到当前的行为:

// internal class ServiceProvider
ServiceEntry entry;
if (_table.TryGetEntry(serviceType, out entry))
{
    return GetResolveCallSite(entry.Last, callSiteChain);
}
如果Microsoft将来会更改此行为,这将是一个严重的突破性更改,不仅会影响.NET Core DI容器的客户端,还会影响第三方容器的所有适配器的客户端

它也会破坏适配器,因为.NET核心容器的行为决定了DI抽象的契约,这也会波及到适配器


因为这种破坏性的改变是如此严重,他们永远无法改变这种行为,这意味着这种行为是有保证的。

即使每次都会得到最后一个,如果你不想要最后一个,你会怎么做?你要循环浏览那个服务集合吗?似乎你甚至不能用内置的IOC容器给每个实例都加上一个名字。在我的例子中,我想要最后一个。但我想知道我可以相信这种行为。(事实上,除非扩展IoC容器,否则无法为每个容器添加名称。在stackoverflow上的某个地方,我看到了一个扩展方法的示例,但不幸的是,当我搜索时,我无法为您找到它。如果您需要,它就在这里的某个地方。)扩展IoC容器。。。这主意不错。我只是使用标记接口。我想说,得到最后一个是有保证的。如果您查看源代码,您会发现这是有保证的,如果他们将来会更改此行为,这将是一个严重的突破性更改,不仅会影响.NET Core DI容器,但是已经编写的第三方容器的所有适配器。@Steven你能用一个到源代码的链接作为答案吗?当你链接到源代码时,你是如何让它链接到GitHub上的实际代码行的?@Ron通过单击行号。