Panoramica su Blazor

Overview della nuova tecnologia di casa Microsoft.

il
Sviluppatore software, Collaboratore di IProgrammatori

Perchè Blazor

Nell'ultimo decennio lo sviluppo di applicazioni web è cresciuto a dismisura, diventando lo standard de-facto per lo sviluppo di applicazioni multipiattaforma (Windows, Mac, Linux) e fruibili in mobilità (tablet, smartphone).

Le applicazioni web prevedono che:

  • L'interfaccia grafica sia sviluppata in linguaggi specifici per il browser (HTML, CSS, JavaScript)
  • L'accesso ai dati venga demandato ad un server centralizzato che rende disponibili i dati stessi mediante appositi endpoint (api) 

Per chi è abituato a sviluppare applicazioni desktop con prodotti di casa Microsoft (Winform o WPF), questo comporta una serie di problemi, fra i quali:

  1. Dover imparare un nuovo linguaggio (HTML + JavaScript) e spesso un nuovo framework di frontend (Angular, Vue, React)
  2. Dover replicare porzioni di codice di backend (c#) nel corrispondente linguaggio di frontend (JavaScript). Si pensi ad esempio agli oggetti di frontiera (DTO) o alle regole di validazione dei dati da inserire

Blazor nasce proprio per semplificare il modo di scrivere le applicazioni web, almeno per chi è abituato ai prodotti di casa Microsoft. Tale tecnologia, infatti, consente di eseguire codice scritto in C# direttamente sul browser, consentendo quindi di:

  1. Sostituire gran parte del codice JavaScript con condice C#
  2. Poter condividere librerie e logiche di business fra la parte server e quella client. Ad esempio si possono condividere tutti gli oggetti di frontiera (DTO) o addirittura condividere le logice più avanzate, quali ad esempio la validazione dei dati

Come funziona Balzor

L'architettura di Blazor prevede che il browser sia in grado di supportare WebAssembly, ovvero uno standard aperto di creazione librerie per il web. L'utilizzo di specifiche standard e aperte consente di utilizzare la tecnologia senza dover installare appositi plugin, come avveniva in passato per Silverlight o Flash.

Viene quindi scaricata sul browser una versione del framework .NET in grado di girare sul browser e convertire le nostre librerie .NET in bytecode eseguibile sulla piattaforma WebAssembly, rendendo le nostre librerie in grado di girare sul browser.

Per la versione server side, ovvero quando il server genera le pagine come faceva ASP.NET, è necessario che il browser supporti anche WebSocket, ovvero una tecnologia che consente di attivare un collegamento bidirezionale fra client e server. Tramite questa tecnologia il server può dare istruzioni al browser su come ridisegnare una pagina (o una sua parte), sgravando il programmatore dall'onere di gestire chiamate AJAX specifiche come si faceva in passato.

Pur essendo WebAssembly e WebSocket protocolli relativamente recenti, vengono già supportati dai browser principali, rendendo Blazor utilizzabile su Edge, Chrome, Safari e via discorrendo.

Applicazione di esempio

Per capire meglio il funzionamento di Blazor, creiamo ed analizziamo il comportamento del template generato dalla CLI. Per farlo eseguiamo dalla linea di comando la seguente istruzione:

dotnet new blazorserver -o TestBlazor

Tramite questo comando viene creata un'applicazione Blazor in modalità server nella cartella TestBlazor.

Analizzando la struttura dell'applicazione possiamo notare:

  • Il file Program.cs che di fatto è l'entry point dell'applicazione. Tramite le chiamate builder.Services.AddServerSideBlazor()app.MapBlazorHub() viene attivato il motore di Blazor lato server
  • La cartella Shared contiene le pagine web condivise, ad esempio il layout principale e la nav bar
  • La cartella Pages contiene le pagine dell'applicazione
  • La cartella wwwroot contiene tutto quello che è javascript e css

Guardiamo ora come è stata implementata la pagina Counter.razor, ovvero una semplice pagina che mostra un numero che può essere incrementato mediante la pressione di un pulsante.

Il codice di tale pagina è il seguente:

@page "/counter"

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
   private int currentCount = 0;

   private void IncrementCount()
   {
      currentCount++;
   }
}

La scrittura della pagina HTML è suddivisa in tre sezioni:

  • La parte iniziale, con la dichiarazione @page, indica il rounting con cui accedere a quella pagina. Nel nostro caso "/counter"
  • Il codice HTML / razor della pagina, ovvero quello compreso fra @page e @code
  • La parte finale, con la dichiarazione @code, in cui c'è il codice C#

Guardando la parte del codice, possiamo notare la variabile privata currentCount che viene inizializzata a zero, quindi viene incrementata dalla funzione IncrementCount. Questa funzione viene richiamata dall'evento @onclick del pulsante "Click me".

Il motore di Blazor consente di rendere funzionante quanto dichiarato con le poche righe di cui sopra. In pratica si occupa di:

  • Generare codice HTML da visualizzare nel browser
  • Intercettare l'evento "on click" ed eseguire la funzione IncrementCount
  • Terminata la funzione, aggiornare la pagina col nuovo valore

Blazor Server vs WebAssembly

Vediamo ora il come la stessa applicazione venga gestita in modo diverso fra la versione server e quella WebAssembly:

  • Nella versione server, la maggior parte del codice viene eseguito lato server. Nell'esempio precedente, il motore di Blazor si occuperà di:
    • Creare lato server il codice HTML da visualizzare nel browser
    • Intercettare l'evento "on click" e dire al server di eseguire la funzione IncrementCount (tramite web-socket)
    • Eseguire il la funzione IncrementCount sul server
    • Al termine della funzione, mandare dal server al client il nuovo valore di currentCount (tramite web-socket)
    • Aggiornare sul client il valore di incrementCount senza ricaricare la pagina
  • Nella versione WebAssembly, la maggior parte del codice viene eseguito lato client. Nell'esempio precedente, il motore Blazor si occuperà di:
    • Inviare al client il framework .NET che consente di convertire il bytecode C# nello standard WebAssembly
    • Inviare al browser la pagina HTML con tanto di codice C# per gestire l'evento
    • Quando si scatena l'evento "on click", eseguire la funzione IncrementCount lato client (WebAssembly)
    • Al termine della funzione, ridisegnare la pagina per aggiornare il valore di incrementCount a video, senza ricaricare la pagina completa

.