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
Usare le navigation property in QuickGrid di Blazor
Utilizzare un numero per gestire la concorrenza ottimistica con SQL Server ed Entity Framework
Aggiungere interattività lato server in Blazor 8
Utilizzare QuickGrid di Blazor con Entity Framework
Eseguire script pre e post esecuzione di un workflow di GitHub
Utilizzare un service principal per accedere a Azure Container Registry
Generare un hash con SHA-3 in .NET
Utilizzare il metodo Index di LINQ per scorrere una lista sapendo anche l'indice dell'elemento
Cancellare una run di un workflow di GitHub
Supporto ai tipi DateOnly e TimeOnly in Entity Framework Core
Come EF 8 ha ottimizzato le query che usano il metodo Contains
Creare alias per tipi generici e tuple in C#
I più letti di oggi
- Simulare Azure Cosmos DB in locale con Docker
- Utilizzare il metodo Index di LINQ per scorrere una lista sapendo anche l'indice dell'elemento
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- .NET Conference Italia 2024 - Milano
- .NET Conference Italia 2023 - Milano e Online