Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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?

like image 874
RonC Avatar asked Mar 02 '17 19:03

RonC


People also ask

Which are the ways dependent services can be registered with the container?

Using method "GetService" of the "HttpContext. RequestServices" property, we can get dependent services configured with the Service container. This is also known as property injection. Following is the example.

Which built-in service container is provided by ASP.NET Core when the dependency is registered in the service container?

The use of an interface or base class to abstract the dependency implementation. Registration of the dependency in a service container. ASP.NET Core provides a built-in service container, IServiceProvider.

What is the difference between transient and Singleton?

Singleton is a single instance for the lifetime of the application domain. Scoped is a single instance for the duration of the scoped request, which means per HTTP request in ASP.NET. Transient is a single instance per code request.

What is IoC container in .NET Core?

ASP.NET Core contains a built-in dependency injection mechanism. In the Startup. cs file, there is a method called ConfigureServices which registers all application services in the IServiceCollection parameter. The collection is managed by the Microsoft.


1 Answers

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.

like image 52
Steven Avatar answered Sep 21 '22 11:09

Steven