简体   繁体   中英

.Net Core Service container, am I guaranteed to get last service registered for the interface?

Question

Using the default Asp.net Core IoC container, am I guaranteed that if multiple object types are registered for an interface and I ask for a service for that interface the IoC will always return the last object type registered for the interface?

(I read through the .Net Core Dependency Injection documentation and it does not seem to address this. https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection )

Demonstration

Let's say I have this interface:

interface ITest
{

    void Create(int id);
}

and these classes:

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;
    }
}

And now in the Startup.cs in the ConfigureServices method I add the following code:

services.AddSingleton<ITest, TestTwo>();
services.AddSingleton<ITest, TestThree>();
services.AddSingleton<ITest, TestOne>();

In the startup.cs Configure method if I write the following code:

 var serviceCollection = app.ApplicationServices.GetServices<ITest>();

I get a collection of thee objects: TestTwo , TestThree and TestOne , in that order.

In the startup.cs Configure method if I write the this code:

var service = app.ApplicationServices.GetService<ITest>();

it always seems to return an instance of the last object registered for the interface, in this case TestOne .

Am I guaranteed that if multiple object types are registered for an interface and I ask for a service for that interface the IoC will always return the last object type registered for the interface?

I would say that getting the last one is -kind of- guaranteed. If you look at the source code you can see the current behavior:

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

If Microsoft would change this behavior in the future, that would be a severe breaking change that not only would impact the clients of the .NET Core DI container, it would impact clients of all adapters for the 3rd party containers as well.

It would break adapters as well, because the behavior of the .NET Core container determines the contract of the DI abstraction and this ripples through to the adapters as well.

Since this breaking change would be so severe, they can never change this behavior, and that implies the behavior is guaranteed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM