.Net Core Service 容器,我能保证为接口注册最后一个服务吗?

Ron*_*n C 5 c# ioc-container asp.net-core-mvc .net-core

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

(我通读了 .Net Core Dependency Injection 文档,它似乎没有解决这个问题 。https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection

示范

假设我有这个界面:

interface ITest
{

    void Create(int id);
}
Run Code Online (Sandbox Code Playgroud)

和这些课程:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在在 Startup.cs 的ConfigureServices方法中添加以下代码:

services.AddSingleton<ITest, TestTwo>();
services.AddSingleton<ITest, TestThree>();
services.AddSingleton<ITest, TestOne>();
Run Code Online (Sandbox Code Playgroud)

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

 var serviceCollection = app.ApplicationServices.GetServices<ITest>();
Run Code Online (Sandbox Code Playgroud)

我得到了一个对象的集合:TestTwo,TestThreeTestOne, 按照这个顺序。

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

var service = app.ApplicationServices.GetService<ITest>();
Run Code Online (Sandbox Code Playgroud)

它似乎总是返回为接口注册的最后一个对象的实例,在这种情况下TestOne

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

Ste*_*ven 4

我想说,获得最后一个是有一定保证的。如果您查看源代码,您可以看到当前的行为:

// internal class ServiceProvider
ServiceEntry entry;
if (_table.TryGetEntry(serviceType, out entry))
{
    return GetResolveCallSite(entry.Last, callSiteChain);
}
Run Code Online (Sandbox Code Playgroud)

如果 Microsoft 将来更改此行为,那将是一个严重的重大更改,不仅会影响 .NET Core DI 容器的客户端,还会影响第 3 方容器的所有适配器的客户端。

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

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

  • @Ron 单击行号。 (2认同)