Dependency Injection e Services in ASP.NET Core

Cosa sono e differenze tra: Singleton, Scoped, Transient

Image for post
Image for post

Introduzione

Per questo motivo sono state inserite “nativamente” molte cose che nella versione precedente potevano solo essere solo aggiunte tramite librerie esterne.

Tra le molte novità spicca il nuovo motore di “Dependency Injection / Ioc”. Senza entrare troppo nel dettaglio, il concetto base della “Dependency Injection” consiste nell’avere un oggetto separato che si occupa della risoluzione delle dipendenze ovvero della loro creazione ed inizializzazione. Queste dipendenze verranno poi iniettate come parametro nel costruttore di un controller, di una classe di business o altro. In questo modo se si ha l’accortezza di usare le interfacce, si otterrà codice debolmente accoppiato e modulare. Che si presta agli unit test.

Image for post
Image for post

Una cosa che valeva anche nella versione precedente era questa. All’interno di un applicazione MVC sono definite varie rotte, quando l’utente digita qualche cosa nel browser il controllo passava al routing, che in base a ciò che è stato digitato stabilisce quale “controller” si deve occupare della richiesta. A questo punto il routing crea in istanza del “controller” e richiama la “action” opportuna. Il nuovo motore di “Dependency Injection” estende la cosa e fa si che dopo che un controller è stato creato vengano anche popolati i parametri del costruttore. Per esempio iniettando automaticamente il DbContext di EntityFramework (se richiesto).

Ciclo di vita e “Dependency Injection”

Image for post
Image for post

Singleton: Un servizio Singleton viene creato solo una volta e quell’istanza viene condivisa ed utilizzata per tutta la durata dell’applicazione. Un servizio Singleton viene creato quando viene richiesto per la prima volta. Per questo motivo, visto che è un servizio condiviso non deve essere usato per memorizzare uno stato. Come suggerisce il nome il metodo AddSingleton() crea un servizio Singleton.

Scoped: Un servizio Scoped viene creato per ogni richiesta e quell’istanza viene condivisa ed utilizzata per tutta la durata della richiesta. Cioè, un’applicazione crea un istanza a fronte di una richiesta http, e quell’ istanza verrà poi condivisa in tutti i posti in cui sarà richiesta nell’ambito della stessa richiesta. Sarà sempre iniettata la stessa istanza. Come suggerisce il nome il metodo AddScoped() crea un servizio Scoped.

Transient: Un servizio Transient viene creato tutte le volte che è richiesto. Verrà sempre iniettata una nuova istanza, anche se la richiesta http è la stessa. Come suggerisce il nome il metodo AddTransient () crea un servizio Transient.

Ovviamente la dependency injection deve essere opportunamente configurata, altrimenti il motore di dependency injection non sa cosa iniettare!

Startup.cs e ConfigureServices() / Configure()

Maggiori informazioni su pipeline e Middleware al seguente quì

In ASP.NET Core abbiamo 2 tipi di servizi che possono essere iniettati

· oggetti buildin

· oggetti custom

Sono da considerarsi “servizi buildin” tutti quei servizi legati a qualche funzionalità presente nel framework o aggiunta tramite NuGet: AppSetting, DbContext di EntityFramework, Autenticazione, etc … Questi servizi avranno poi un proprio ciclo di vita e potranno essere: Singleton, Scoped, Transient (anche se questo non è deciso da noi). Nel metodo ConficureServices() è anche possibile effettuare la configurazione di un servizio. Alcuni servizi sono disponibili anche senza essere registrati nel metodo ConficureServices(): IApplicationBuilder, IHostingEnvironment.

Sono da considerarsi “servizi custom” tutti quei servizi definiti in una nostra libreria (per esempio servizi di business). Questi servizi possono essere iniettati come: Singleton, Scoped, Transient (in questo caso siamo noi a decidere la modalità).

Oggetti buildin

AppSettings

public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<AppSettings>(Configuration.GetSection(“AppSettings”));
}

Il codice sovrastante configura l’ oggetto AppSettings i cui valori verranno letti dal file appsettings.json. In questo modo sarà possibile iniettarlo all’interno di un controller o in una classe di business tutte le volte che è richiesto.

public class AuthController : Controller
{
private AppSettings appsettings;
private IHostingEnvironment host;
public AuthController(IOptions<AppSettings> options, IHostingEnvironment server)
{
appsettings = options.Value;
host = server;
}
}

Nel codice sovrastante possiamo vedere un controller nel quale è iniettato l’oggetto AppSettings.

DbContext di EntityFramework

public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<appstudentiContext>(options => options.UseSqlServer(
Configuration.GetConnectionString(“DefaultConnection”)));
}

Il codice sovrastante configura l’ oggetto DbContext di EntityFramework. In questo modo sarà possibile iniettarlo all’interno di un controller o in una classe di business tutte le volte che è richiesto.

public class CoursesManager : ICoursesManager
{
private AppSettings appsettings;
private appstudentiContext db;
public CoursesManager(IOptions<AppSettings> options, appstudentiContext context)
{
appsettings = options.Value;
db = context;
}
}

Nel codice sovrastante possiamo vedere una classe di business nel quale è iniettato il DbContext di EntityFramework. Quest’oggetto viene iniettato in modalità scoped.

Oggetti custom

public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<ITeachersManager, TeachersManager>();
services.AddTransient<IStudentsManager, StudentsManager>();
}

Il codice sovrastante registra 2 oggetti (TeachersManager e StudentsManager) che potranno poi essere iniettati dove richiesto.

public class TeachersController : Controller
{
private AppSettings appsettings;
private IHostingEnvironment host;
private ITeachersManager tm;
public TeachersController(IOptions<AppSettings> options, IHostingEnvironment server, ITeachersManager teachersmanager)
{
appsettings = options.Value;
host = server;
tm = teachersmanager;
}
}

Nel codice sovrastante possiamo vedere un controller nel quale è iniettato un oggetto di tipo ITeachersManager precedentemente registrato in modalità Transient. Verranno anche iniettati AppSettings e IHostingEnvironment.

Conclusioni

Che cosa è ASP.NET MVC Core e vantaggi apportati dal pattern MVC

Se volete contattarmi il mio profilo Linkedin è il seguente: Stefano Marchisio: Consulente freelance Angular ASP.NET MVC C#

Sono uno sviluppatore web full-stack: Angular / TypeScript e ASP.NET MVC CORE C# https://www.stefanomarchisio.it/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store