2016-03-08 12 views
18

Ho un servizio che viene iniettato in un controller utilizzando contenitore Dependency Injection di default del Nucleo ASP.NET:Come liberare risorse e smaltire il servizio inserito in ASP.NET 5/Core entro la fine della richiesta?

public class FooBarService : IDisposable { 
    public void Dispose() { ... } 
} 

services.AddScoped<FooBarService>(); 

Questo crea un'istanza per ogni richiesta. Come garantire che il framework disponga l'istanza FooBarService entro la fine di ogni richiesta, senza fare affidamento su distruttori e garbage collection?

risposta

22

Come tutti gli altri contenitori DI, disporrà di istanze IDisposable per voi rispettando la durata della vita di esempio.

Nella vostra richiesta, se l'istanza è registrata come Scoped (Istanza per richiesta). Disporrà questa istanza dopo che la richiesta è stata completata.

Modifica: Nei documenti ufficiali non lo menzionano. Quindi cerchiamo di controllare il codice sorgente per essere sicuri:

Quando viene creato un ambito, ServiceScopeFactory restituisce un nuovo ServiceScope che è dipendeva con ServiceProvider e getta.

ServiceProvider ha private List<IDisposable> _transientDisposables; che mantiene servizi monouso quando TransientCallSite è invoke d in CaptureDisposable metodo. Anche ServiceProvider ha private readonly Dictionary<IService, object> _resolvedServices = new Dictionary<IService, object>(); che mantiene tutti i servizi per Scoped.

Al termine del sollevamento/dell'ottica, lo ServiceScope viene smaltito. Quindi dispone di ServiceProvider che dispone di tutte le _transientDisposables e quindi controlla _resolvedServices e dispone di servizi monouso nel dizionario in ServiceProvider.

Modifica (13.06.2017): menzionano nei documenti ufficiali ora. Disposing of services

+0

Non riesco a trovare un posto nella documentazione, dove si dice di smaltire direttamente. Potresti indicarmi il testo giusto? – dmigo

+0

[Gestisce la durata (quando creare un oggetto e quando eliminarlo) dell'oggetto iniettato.] (Http://www.binaryintellect.net/articles/7751fa4c-5638-4090-bb4a-4c5f0a2513da.aspx) –

+0

Ho il problema con questo. Ho aggiunto un contesto di archiviazione dati come AddScoped. Ora sembra che sia stato riutilizzato. Il costruttore viene colpito solo uno per più richieste e Dispose non viene mai richiesto. Il mio limite sul DB Document sembra che il lode sia costante. In qualsiasi modo posso controllare cosa non è corretto? Ho anche creato l'Id prperty come: this.id = Guid.Newuid(); ed è lo stesso per tutte le richieste. –

4

Quando si utilizza AddScoped è by design che l'oggetto avrà una durata associata alla richiesta.

2

Non vedo nessuno menzionato ancora questo, ma oltre all'implementazione di IDisposable nel tuo tipo, puoi anche utilizzare {HttpContext}.Response.RegisterForDispose(objectToDispose). Tipicamente questo è usato per registrare un oggetto all'inizio di una richiesta (come un'azione del controllore) da smaltire quando termina la richiesta.