ASP.NET Core – Beware – Singleton May Not Be Singleton

If you register a type as a singleton then you expect just 1 instance of this type in your whole application. What you may not know is that ASP.NET Core is creating 2 instances of IServiceProvider during building of the IWebHost that may lead to 2 instance of your "singleton".

In diesem Artikel:

ASP.NET Core – Beware – Singleton May Not Be Singleton
Pawel Gerr ist Architekt und Consultant bei Thinktecture. Er hat sich auf .NET Core Backends spezialisiert und kennt Entity Framework von vorne bis hinten.
This is the case if you register a type, say MySingleton, when configuring the web host …
				
					WebHost
 .CreateDefaultBuilder()
 .UseStartup<Startup>()
 .ConfigureServices(services => services.AddSingleton<MySingleton>())
 .Build()
 .Run();
				
			

 …, e.g. so that is available in the constructor of your Startup

				
					public class Startup
{
  private readonly MySingleton _mySingletonFromHostingServiceProvider;

  public Startup(MySingleton mySingletonFromHostingServiceProvider)
  {
    _mySingletonFromHostingServiceProvider = mySingletonFromHostingServiceProvider;
  } 
  ...
}
				
			

Now, if we resolve MySingleton during normal web request we get a whole new instance instead the same instance as in constructor of the Startup class. 

				
					public void Configure(IApplicationBuilder app)
{
  app.Use((ctx, next) =>
  {
    var mySingleton = ctx.RequestServices.GetRequiredService<MySingleton>();
    
    // the comparison of 2 instances yields "false"
    var areEqual = _mySingletonFromHostingServiceProvider == mySingleton;

    Console.WriteLine($"==> {nameof(_mySingletonFromHostingServiceProvider)} == {nameof(mySingleton)}: {areEqual}");
         return next();
    });
}
				
			

 There are at least two ways to fix this problem.

Either pass an instance of MySingleton to method AddSingleton instead of passing just the type

				
					var mySingleton = new MySingleton();
WebHost
 .CreateDefaultBuilder()
 .UseStartup<Startup>()
 .ConfigureServices(services => services.AddSingleton(mySingleton))
 .Build()
 .Run();
				
			

 or by replacing the previous registration with a new one in ConfigureServices 

				
					public class Startup
{
  private readonly MySingleton _mySingletonFromHostingServiceProvider;

  public Startup(MySingleton mySingletonFromHostingServiceProvider)
  {
     _mySingletonFromHostingServiceProvider = mySingletonFromHostingServiceProvider;
  }

  public void ConfigureServices(IServiceCollection services)
  {
    services.Replace(new ServiceDescriptor(typeof(MySingleton), _mySingletonFromHostingServiceProvider));
    // alternative way 
    //services.AddSingleton(_mySingletonFromHostingServiceProvider);
 }
  ...
}
				
			

According to @davidfowl the ASP.NET team will address this problem in the future. 

PS: There is at least another one solution to fix this problem and gaining back the control over your web app but that’s for another time … 🙂

Kostenloser
Newsletter

Aktuelle Artikel, Screencasts, Webinare und Interviews unserer Experten für Sie

Verpassen Sie keine Inhalte zu Angular, .NET Core, Blazor, Azure und Kubernetes und melden Sie sich zu unserem kostenlosen monatlichen Dev-Newsletter an.

Diese Artikel könnten Sie interessieren
Unterschiede
.NET
Blazor WebAssembly vs. Blazor Server – Welche Unterschiede gibt es und wann wähle ich was?

Blazor WebAssembly vs. Blazor Server – Welche Unterschiede gibt es und wann wähle ich was?

Das Blazor Framework von Microsoft gibt es inzwischen in drei "Geschmacksrichtungen". Die erste ist Blazor WebAssembly, die zweite Blazor Server, und zu guter Letzt gibt es noch Blazor Hybrid. In diesem Artikel wollen wir uns die zwei "echten", also Browser-basierten, Web-Anwendungs-Szenarien WebAssembly und Server anschauen.
04.07.2022
Three different textured walls
.NET
Dependency Injection Scopes in Blazor

Dependency Injection Scopes in Blazor

The dependency injection system is a big part of how modern ASP.NET Core works internally: It provides a flexible solution for developers to structure their projects, decouple their dependencies, and control the lifetimes of the components within an application. In Blazor - a new part of ASP.NET Core - however, the DI system feels a bit odd, and things seem to work a bit differently than expected. This article will explain why this is not only a feeling but indeed the case in the first place and how to handle the differences in order to not run into problems later on.
31.05.2022
ASP.NET Core
ASP.NET Core Blazor WebAssembly: Authentifizierung und Autorisierung mit Keycloak in Aktion

ASP.NET Core Blazor WebAssembly: Authentifizierung und Autorisierung mit Keycloak in Aktion

Im ersten Teil der Artikelserie haben wir uns angesehen, wie sich ein Blazor-WebAssembly-Client mit Hilfe eines Identity Providers (IDP) sicher mit einer Web API kommunizieren kann. Hierzu wurde IdentityServer als IDP genutzt. In diesem Teil widmen wir uns einem alternativen IDP, nämlich Keycloak. Wie auch im vorherigen Artikel, betrachten wir hier die Authentifizierung des Blazor-Clients und wie wir die Client-UI anhand von Autorisierungsinformationen anpassen können.
07.12.2021
ASP.NET Core
ASP.NET Core Blazor WebAssembly: Performance-Optimierung auf Komponentenebene

ASP.NET Core Blazor WebAssembly: Performance-Optimierung auf Komponentenebene

Stockende UI, keine Reaktion nach dem Klick auf einen Button oder einer Eingabe in einem Feld - dies sind nur wenige Beispiele alltäglicher Probleme, die der Nutzung von Client-Anwendungen im Allgemeinen, und bei Webanwendungen im Speziellen, immer wieder auftreten können. In diesem Artikel schauen wir uns an, wie wir komponentenbasierte UIs in Blazor WebAssembly optimieren können, um dadurch eine für die Benutzer zufriedenstellende Geschwindigkeit und ein flüssiges UI zu bekommen.
21.10.2021
ASP.NET Core
Architects Briefing: Die 9 wichtigsten Blazor WebAssembly-Neuerungen in .NET 5

Architects Briefing: Die 9 wichtigsten Blazor WebAssembly-Neuerungen in .NET 5

Dieser Artikel basiert auf den Inhalten des Webinars 'Blazor WebAssembly: Neues in .NET 5' und soll eine kurze Zusammenfassung der wichtigsten Punkte liefern. Hier finden Sie alle Details, das Slidedeck, die zahlreichen technischen Demos, das Webinarvideo und der Source Code.
20.08.2021
.NET
Modular Monoliths With ASP.NET Core – Pragmatic Architecture

Modular Monoliths With ASP.NET Core – Pragmatic Architecture

Thinking and even recommending a monolithic architecture these days seems antiquated. While a microservices architecture clearly has its benefits, it also comes with drawbacks. Sometimes these drawbacks can be more significant than the benefits and might hinder your development, time-to-market, or your ability to maintain your application.
30.06.2021