Blazor è il primo framework puramente front-end sviluppato da Microsoft, nato rispettando i più moderni standard web, tra questi la possibilità di essere installato su un dispositivo emulando un'applicazione vera e propria. Questo approccio, chiamato PWA, è configurabile già in fase di creazione del progetto, spuntando una checkbox. Benche in alcuni casi sia più che sufficiente, in realtà non è che l'inizio!
In un'applicazione sviluppata per essere una PWA bisogna tenere in considerazione che l'utente potrebbe accedere in modalità offline oppure in un luogo in cui non vi è connettività, al che l'unica cosa che vedrà sarà l'interfaccia, perchè i dati, essendo recuperati tramite servizi remoti, non saranno disponibili. Da qui nasce la necessità di cambiare approccio di sviluppo: parliamo di creare applicazioni in modalità Offline First, dove i dati, o una parte di essi, una volta scaricati, vengono salvati all'interno del browser e sincronizzati successivamente con il server.
Un luogo di allocazione può essere il LocalStorage: come abbiamo visto negli scorsi script, in cui salvavamo le scelte di configurazione dell'utente, ma esso ha un limite di memoria pari a 5MB, e non possiede buone prestazioni in lettura/scrittura. Potremmo usare il SessionStorage che ha una memoria illimitata, ma volatile, quindi non adatta.
A lato di queste tecnologie che permettono un salvataggio locale troviamo IndexedDB, che potremmo definire un database integrato nel browser, nel quale possiamo salvare qualsiasi tipologia ed effettuare query in lettura.
L'implementazione in Blazor parte dall'utilizzo della libreria DnetIndexedDb installabile tramite NuGet, e di una libreria custom, allegata a questo script, contenente una serie di metodi che facilitano l'interfacciamento verso IndexedDB.
<ItemGroup> <.. /> <PackageReference Include="DnetIndexedDb" Version="2.3.1" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\IndexDbHelpers\IndexDbHelpers.csproj" /> </ItemGroup>
Il secondo passo consiste nella creazione di un contesto, così come avviene per Entity framework, estendendo la classe IndexedDbInterop ed un modello, al quale applicare gli attributi necessari per effetture le query
public class ApplicationIndexDb : IndexedDbInterop { public ApplicationIndexDb(IJSRuntime jsRuntime, IndexedDbOptions<ApplicationIndexDb> options) : base(jsRuntime, options) { } } public class SampleContract { [IndexDbKey] public string Id { get; set; } [IndexDbIndex] public string Name { get; set; } }
È importante notare che il modello non è stato definito all'interno del contesto, infatti l'assegnazione avverrà nel file Program.cs, nel quale inseriremo tra i servizi l'accesso al database IndexedDB, al cui interno vi sarà una tabella per SampleContract.
builder.Services.AddIndexedDbDatabase<ApplicationIndexDb>(options => { var indexedDbDatabaseModel = new IndexedDbDatabaseModel() // nome .WithName(nameof(ApplicationIndexDb)) // versione .WithVersion(1); // tabelle indexedDbDatabaseModel.AddStore<SampleContract>(); options.UseDatabase(indexedDbDatabaseModel); });
A questo punto nella pagina, o servizio, designato possiamo accedere al database tramite dependecy injection.
@page "/samples" @using IndexDbHelpers @inject ApplicationIndexDb context <p>Current count: @list.Count</p> <button class="btn btn-primary" @onclick="Add">Add!</button> @code { private IList<SampleContract> list = new List<SampleContract>(); private async Task Add() { // connessione al DB var openResult = await context.OpenIndexedDb(); // aggiunta item await context.AddItems(new List<SampleContract> { new() { Id = Guid.NewGuid().ToString(), Name = $"Contract {DateTime.Now}" } }); // lettura items list = await context.GetAll<SampleContract>(); } }
Infine, dobbiamo ricordare che tutte le operazioni, che dialogano con IndexedDB, utilizzano Interop Javascript, è quindi necessario importare lo script per gestire queste chiamate. All'interno di index.html aggiungiamo
<script src="_content/DnetIndexedDb/rxjs.min.js"></script> <script src="_content/DnetIndexedDb/dnet-indexeddb.js"></script>
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Eseguire query manipolando liste di tipi semplici con Entity Framework Core
Utilizzare la funzione EF.Parameter per forzare la parametrizzazione di una costante con Entity Framework
Migrare una service connection a workload identity federation in Azure DevOps
Proteggere le risorse Azure con private link e private endpoints
Utilizzare QuickGrid di Blazor con Entity Framework
Eseguire script pre e post esecuzione di un workflow di GitHub
Usare le navigation property in QuickGrid di Blazor
L'evoluzione di Blazor in .NET 8
Creare una libreria CSS universale - Rotazione degli elementi
Supportare il sorting di dati tabellari in Blazor con QuickGrid
Disabilitare automaticamente un workflow di GitHub
Miglioramenti nell'accessibilità con Angular CDK