Nicht konsumieren können, scoped service IMongoDbContext von singleton IActiveUsersService nach upgrade auf ASP.NET Core 2.0
Ich aktualisiert, ein Projekt zu ASP.NET Core 2 heute und ich bekomme die folgende Fehlermeldung:
Nicht verbrauchen kann, scoped service IMongoDbContext von singleton IActiveUsersService
Habe ich folgende Eintragung:
services.AddSingleton<IActiveUsersService, ActiveUsersService>();
services.AddScoped<IMongoDbContext, MongoDbContext>();
services.AddSingleton(option =>
{
var client = new MongoClient(MongoConnectionString.Settings);
return client.GetDatabase(MongoConnectionString.Database);
})
public class MongoDbContext : IMongoDbContext
{
private readonly IMongoDatabase _database;
public MongoDbContext(IMongoDatabase database)
{
_database = database;
}
public IMongoCollection<T> GetCollection<T>() where T : Entity, new()
{
return _database.GetCollection<T>(new T().CollectionName);
}
}
public class IActiveUsersService: ActiveUsersService
{
public IActiveUsersService(IMongoDbContext mongoDbContext)
{
...
}
}
Warum DI nicht zu verbrauchen, das service? Alle funktioniert gut für ASP.NET Core 1.1.
Warum willst du das überhaupt haben die Mongo Kontext beschränkt werden, in Erster Linie? Haben Sie irgendeine Art von Mieter-Funktionalität, wo man weiß, die Mandanten-id erst zur Laufzeit? MongoDatabase ist thread-sicher, so können Sie auch halten Sie es als singleton (vorausgesetzt, Sie laufen nicht 100te davon halten, zu viele verbindungen öffnen). EF-Core auf der anderen Seite ist nicht thread-safe und hat einen caching-Mechanismus standardmäßig aktiviert (EF-Core-tracking fungiert auch als caching), so ist es natürlich, es zu haben scoped)
Möglich, Duplikat der Verwenden DbContext in ASP .Net Singleton Injiziert Klasse
Möglich, Duplikat der Verwenden DbContext in ASP .Net Singleton Injiziert Klasse
InformationsquelleAutor user348173 | 2017-08-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie nicht verwenden Sie einen Dienst mit einer geringeren Lebensdauer. Scoped services existieren nur pro-Anfrage, während singleton-Dienste werden einmal erstellt und die Instanz freigegeben ist.
Nun nur eine Instanz von
IActiveUsersService
existiert in der app. Aber Sie will angewiesen sein aufMongoDbContext
, die ausgelegt ist, und erstellt pro Anfrage.Müssen Sie entweder:
MongoDbContext
ein Singleton ist, oderIActiveUsersService
Einfache, oderMongoDbContext
in der user-Dienst als eine Funktion argumentMyService
zum Beispiel, ist der Gültigkeitsbereich, und ich will GültigkeitsbereichMongoDbContext
für diesen service.Sie können nicht verschiedene Leben (ohne andere Schnittstellen, zum Beispiel). Warum wollen Sie ein scoped version für das one? Wenn ein Dienst singleton ist, es sollte singleton. Wenn es nicht kann, aber es kann eingeschränkt werden, es sollte eingeschränkt werden. Wenn es nicht beschränkt werden, es sollte vorübergehend sein.
Ja, dumme Frage:) Danke, für die Antwort.
Danke, macht absolut Sinn - aber ich Frage mich, warum es möglich war, in ASP.NET Core 1.0? War ein bisschen verwirrend.
Ich denke, der Fehler war nur in 2.0. In bestimmten Situationen kann es funktioniert haben, aber im Grunde sollten Sie es nicht tun.
InformationsquelleAutor juunas
Gibt es wichtige Unterschiede zwischen den Gültigkeitsbereich und die Singleton-services. Die Warnung ist da, um zu bringen das Licht, und drehen Sie es aus oder Schalt um Leben wahllos um es Weg lösen nicht das problem.
Scoped services sind erstellt aus einer
IServiceScope
. Eines seiner wichtigsten Ziele besteht darin, sicherzustellen, dass alleIDisposable
Dienste, die erstellt werden, in diesem Bereich ordnungsgemäß entsorgt werden, wenn der Umfang selbst ist.In ASP.NET Kern, ein service-Bereich wird automatisch für Sie erstellt, die auf jede eingehende Anfrage, so dass Sie normalerweise nicht brauchen, zu kümmern. Sie können jedoch auch Ihre eigenen service-Bereich, brauchen Sie nur entsorgen es selbst.
Einen Weg, dies zu tun ist, um:
IDisposable
,IServiceProvider
,IServiceScope
Umfang mit demIServiceProvider.CreateScope()
Erweiterung Methode,Dispose
Methode.Je nachdem, wie du mit diesen und den scoped services, die Sie verbraucht sind, könnten Sie stattdessen eine der folgenden:
IServiceProvider
verwenden Sie es zum erstellen einer neuenIServiceScope
innerhalb einerusing
block jedes mal, wenn Sie brauchen, ein scoped-service, und lassen Sie die Rahmen werden entsorgt, wenn der block beendet wird.Nur im Hinterkopf behalten, dass jede
IDisposable
services erstellt aus einerIServiceScope
erhalten automatisch entsorgt, wenn der Umfang selbst.Kurz gesagt, nicht nur um ändern die Lebensdauer Ihre Dienstleistungen zu "make it work"; Sie müssen noch zu denken und sicher sein, Sie bekommen, entsorgt. ASP.NET Griffe in den meisten gebräuchlichen Fällen automatisch, für die anderen, Sie brauchen nur zu tun, ein bisschen mehr Arbeit.
Seit C# 1.0 hatten wir
using()
Blöcke der Mittel sicherzustellen sind korrekt entsorgt. Aberusing()
blocks funktionieren nicht, wenn etwas anderes (DI-service) erstellen diese Ressourcen für Sie. Das ist, wo Scoped services kommen, und mit Ihnen falsch führen zu Ressourcen-Lecks in Ihrem Programm.BeginScope()
entsprichtServiceProviderServiceExtensions.CreateScope()
? Vielleicht wurde es umbenannt?ja, es ist nicht sicher, ob Sie umbenannt wurde oder ich einfach falsch eingegeben, aber ich fixe das Beispiel & link Hinzugefügt, danke!
InformationsquelleAutor Toby J
Können Sie auch hinzufügen,
bevor
.Build()
imProgram.cs
- Datei zum deaktivieren der Validierung.Versuchen Sie dies nur für Entwicklungs -, Test -, ActiveUsersService ist singleton und hat eine größere Lebensdauer als MongoDbContext, die den Gültigkeitsbereich und werden nicht entsorgt.
InformationsquelleAutor Robin Thomas
Gibt es eine andere Annäherung an dieses Problem, und es ist durch das hinzufügen der
MongoDbContext
zu den DI alsAddTransient
wie diese:Die Bedeutung dieses Ansatzes ist, dass Sie am Ende mit einer Instanz von
MongoDbContext
für jedenSingleton
Klasse, die Sie haben, es zu benutzen.Zum Beispiel, wenn Sie 10 Singleton-Klassen mit
MongoDbContext
musst du 10 Instanzen von es, aber es ist statt dem erstellen einer Instanz für einen jeden Wunsch.Sehen Referenz: Nicht Konsumieren können, Scoped Service Von Singleton – Eine Lektion In ASP.net Kern DI Bereiche
InformationsquelleAutor Liran Friedman