Service Model ============================ Il modello a servizi di .NET Core permette la registrazioni di tipi, factory o istanze che vengono poi utilizzate attraverso il :ref:`Service Injecting`. Il pattern prevede 2 fasi principali. La prima è di registrazione dei servizi mentre la seconda è quella di esecuzione del programma in cui i servizi vengono utilizzati. La necessità di questo pattern di definizione-implementazione permette di creare applicativi estendibili senza particolari sforzi e incremento di complessità generati dalla creazione di pattern ad-hoc per l'estindibilità di librerie condivise Registrazione Serivizi -------------------------- La registrazione dei servizi avviene tramite numerosi metodi di estensione di un'istanza di ``IServiceCollection``. Un servizio può riferirsi ad un'interfaccia, ad una classe astratta o direttamente ad una classe implementata. Il services model, però, suggerisce di utilizzare un sistema di interfaccia-implementazione per componenti esterne e, nel caso in cui fosse necessario, l'utilizzo diretto di classi implementate per servizi di utility presenti negli applicativi finali. Services Lifetimes ---------------------- Il sistema permette l'aggiunta di 3 tipi di servizio: Singleton Il tipo di servizio più semplice che permette di aggiungere un'istanza condivisa globale per tutto il lifetime del ServiceProvider a cui viene aggiunta Scoped Il tipo scoped permette di aggiungere un'istanza condivisa per ogni scope del ServiceProvider a cui viene aggiunta Transient Il tipo transient creerà una nuova istanza del servizio ogni volta che esso verrà richiesto .. note:: Il concetto di *Scope* in ASP.NET Core viene inteso come suddivisione per richiesta ed è possibile ottenere il provider di riferimento per ogni richiesta dalla proprietà ``HttpContext.RequestServices`` ASP.NET Core -------------- Nel caso di ASP.NET Core le due fasi sopra citate vengono riassunte nel file `Startup.cs` e, più precisamente, nei due metodi ``ConfigureServices`` e ``Configure`` che, rispettivamente, permettono di aggiungere nuovi servizi all'applicativo e impostare l'ordine di esecuzione dei :ref:`middleware` che li utilizzeranno. Gli standard per l'aggiunta di librerie suggeriscono l'utilizzo di metodi di estensione per aggiungere i servizi necessari all'uso di determinate funzionalità. .. literalinclude:: service-model-startup-example.cs :linenos: :language: c# .. note:: La configurazione dei servizi aggiunti, solitamente, avviene o tramite delegari passati come parametri (solitamente opzionali) oppure tramite il tipo di ritorno del metodo di estensione che può fungere da builder per l'aggiunta e la configurazione avanzata di funzionalità In entrambi i metodi è molto importante l'ordine in cui vengono eseguiti i metodi di aggiunta in quanto nel primo caso le librerie tenteranno sempre di aggiungere i servizi con ``TryAdd[TIPO]`` in modo da permettere allo sviluppatore di registrare il servizio in questione prima di chiamare il metodo di aggiunta sovrascrivendo il servizio originale. Nel secondo caso, invece, cambia :ref:`l'ordine di esecuzione dei middleware`. Un esempio di override può avvenire nel caso del servizio di autenticazione della libreria `WebCore` .. code-block:: c# services.AddSingleton(); // Oppure services.AddScoped(new CustomAuthenticationService("some custom parameter")); services.AddScoped(); // Oppure services.AddScoped(provider => new CustomAuthenticatorService("some custom parameter", provider.Resolve())); services.AddWebCoreAuthentication(); .. important:: Se il metodo di estensione verrà chiamato prima dell'aggiunta dei servizi personalizzati verrà generato un errore per il tentativo di aggiunta di un servizio preesistente .. toctree::