skip to Main Content

I have ASP.NET WebApi with one service which is added as a singleton in the following way:

services.AddSingleton<IService, Service>();

As I can see constructor of this service is called not once (like we suppose to be as a singleton) but multiple times. From what I understand it’s executed once per thread. Thread pool contains multiple threads.

And question is. Is one thread from the pool reused? Is it true and possible that another request will get the instance of service which was created by earlier request? Seems that yes and it’s why we should use AddSingleton only for stateless services. But to be honest I don’t know how to check it and simulate the case to get instance of service which was created earlier.

Or I understand it incorrectly?

Tried to execute multiple request to get the same instance of the service.

2

Answers


  1. The pool threads are reused. If you add it to the services as you did and use dependency injection everyone who accesses your server will have the same instance. So for example :
    Your service has an : int foo=Random.Range(0,5) and the value is now 5
    everyone will see this singleton with the int foo=5 .
    If you use for example : ‘AddScoped‘ instead of ‘AddSingleton‘ everyone will have a new instance of the object. So someone would see foo=1 , another one will see foo=3 and so on.

    So yes the service will get the instance that was created earlier.
    I hope I was able to clarify it for you 🙂

    Login or Signup to reply.
  2. MS.DI will guarantee that the constructor of a singleton is only called at most once, even in a multi-threaded environment, except when:

    • That class is registered multiple times, e.g.:
      // Both registrations have their own single instane
      services.AddSingleton<IService, Service>();
      services.AddSingleton<Service>();
      
    • When you built multiple container’s, as each container will have its own set of singletons, e.g.:
      // Both registrations have their own single instane
      services.AddSingleton<IService, Service>();
      var c1 = services.BuildServiceProvider();
      var c2 = services.BuildServiceProvider();
      Assert.AreNotEqual(c1.GetService<IService>(), c2.GetService<IService>());
      

    Whether or not singletons are resolved from multiple threads doesn’t change the fact that a single container guarantees only one instance of a singleton.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search