2017-07-03 2 views
3

Ich versuche, so etwas wie diese Funktion zu erhalten:Injizieren einer Fabrik Func mit ASP.NET Core-DI

public class FooService : IFooService { 
    public FooService(Func<IBarService> barFactory) { ... } 
} 
public class BarService : IBarService, IDisposable { ... } 

services.AddSingleton<IFooService, FooService>(); 
services.AddTransient<IBarService, BarService>(); 
services.AddSingleton<Func<IBarService>>(ctx =>() => ctx.GetService<IBarService()); 

Das funktioniert so weit wie die Lösung des BarService Instanz, aber ich kann nicht herausfinden, wie man richtig verwalten seine Lebensdauer. Wenn ich dies tun in einer der Mitglieder der FooService:

using (var bar = _barFactory()) 
{ 
    ... 
} 

Ich erhalte eine ObjectDispoedException:

System.ObjectDisposedException: keine angeordneten Objekt zugreifen können. Eine häufige Ursache für diesen Fehler ist die Bereitstellung eines Kontexts, der aus der Abhängigkeitsinjektion gelöst wurde und später an anderer Stelle in Ihrer Anwendung dieselbe Kontextinstanz verwenden soll. Dies kann auftreten, wenn Sie Dispose() für den Kontext aufrufen oder den Kontext in einer using-Anweisung umbrechen. Wenn Sie die Abhängigkeitsinjektion verwenden, sollten Sie den Dependency-Injektionscontainer veranlassen, Kontextinstanzen zu entfernen.

Allerdings, wenn ich var bar = _barFactory(); nur tun, ohne die Anweisung using, habe ich keine Möglichkeit zum DI-Containern zu signalisieren, dass ich mit dem Fall fertig bin, und es kann entsorgt werden.

Was ist der richtige Ansatz hier?


(Randbemerkung:. Ja, ich weiß, dass einige Objekt wird, dass ein Singleton-Dienst nicht auf einem vorübergehenden Dienst abhängig sein sollte, das ist nicht das, was hier geschieht, die Singleton-Dienst ist abhängig von einer Singleton Fabrik, dass produziert vorübergehende Instanzen die Singleton dann die transiente Dienst verwendet für ein oder zwei Aussagen und dann mit ihr geschehen, so sollte es keine tatsächliche Lebensdauer Probleme hier)

Antwort

2

Wie in documentation beschrieben:..

Der Container ruft Dispose für IDisposable Typen auf, die er erstellt. Wenn Sie jedoch dem Container selbst eine Instanz hinzufügen, wird diese nicht verworfen.

Also einfach nicht using Anweisung verwenden und alles sollte in Ordnung sein.

+0

Aber * wann * wird es 'Dispose' nennen? Woher weiß es, dass ich mit der Instanz fertig bin? –

+1

@TomasLycken Container hat 'List ' und es verfügt über "Transient" und "Scoped" Objekte am Ende des Bereichs (Standard ASP.NET Core-Bereich ist Web-Anfrage). https://stackoverflow.com/a/40845639/5112433 –