Créer une App Moderne — Avalonia UI & .NET

💾 Module 6 — La persistance locale en JSON

Conserver les tâches après fermeture de l'application sans modifier le ViewModel.

Créer une App Moderne — Avalonia UI & .NET

📝 Changelog

  • Ajout d'un JsonTodoRepository.
  • Remplacement du stockage mémoire par un stockage disque.
  • Le comportement UI reste identique, seule l'infrastructure change.
  • V0.0.4 : remplacement du squelette par une implémentation System.Text.Json complète et fonctionnelle.
Créer une App Moderne — Avalonia UI & .NET

Objectif du module

  • Sauvegarder les tâches sur disque.
  • Recharger la liste au démarrage.
  • Montrer la valeur du polymorphisme.
  • Consolider la frontière entre application et infrastructure.
Créer une App Moderne — Avalonia UI & .NET

Pourquoi le JSON est une bonne étape intermédiaire

  • Facile à inspecter.
  • Facile à sérialiser.
  • Suffisant pour un prototype desktop mono-utilisateur.
  • Prépare bien le passage à un backend distant.
Créer une App Moderne — Avalonia UI & .NET

Exemple d'implémentation

public sealed class JsonTodoRepository : ITodoRepository
{
    private readonly string _filePath =
        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                     "TodoApp", "todos.json");

    public async Task<IReadOnlyList<TodoItem>> GetAllAsync()
    {
        if (!File.Exists(_filePath)) return Array.Empty<TodoItem>();
        var json = await File.ReadAllTextAsync(_filePath);
        return JsonSerializer.Deserialize<List<TodoItem>>(json) ?? new();
    }

    public async Task AddAsync(TodoItem item)
    {
        var items = (await GetAllAsync()).ToList();
        items.Add(item);
        Directory.CreateDirectory(Path.GetDirectoryName(_filePath)!);
        await File.WriteAllTextAsync(_filePath,
            JsonSerializer.Serialize(items, new JsonSerializerOptions { WriteIndented = true }));
    }
}
[{ "title": "Préparer la démo", "isDone": false }]
Créer une App Moderne — Avalonia UI & .NET

Le concept clé: polymorphisme

  • Le ViewModel continue d'appeler ITodoRepository.
  • On injecte maintenant une autre implémentation.
  • Aucune réécriture métier n'est nécessaire.
  • Le contrat stabilise le système.
Créer une App Moderne — Avalonia UI & .NET

Illustration du flux JSON

Créer une App Moderne — Avalonia UI & .NET

Schéma Mermaid de lecture/écriture

Créer une App Moderne — Avalonia UI & .NET

Points techniques à traiter

  • Chemin de fichier portable.
  • Gestion du premier lancement si le fichier n'existe pas.
  • Sérialisation asynchrone.
  • Tolérance aux fichiers vides ou corrompus.
Créer une App Moderne — Avalonia UI & .NET

Injection au démarrage

services.AddSingleton<ITodoRepository, JsonTodoRepository>();
services.AddSingleton<TodoListViewModel>();
  • La composition racine décide du stockage actif.
Créer une App Moderne — Avalonia UI & .NET

Livrable du module

  • Les tâches survivent à un redémarrage.
  • Le ViewModel n'a pas changé.
  • L'équipe comprend la force d'une architecture par contrat.
Créer une App Moderne — Avalonia UI & .NET

🔗 Repo de référence

🌐 https://gitlab.bzctoons.net/ynov/b3-dev-tasklis

  • Branche module-06-persistance → état du projet à la fin de cette séance.
  • En cas de blocage: git checkout module-06-persistance pour repartir d'une base saine.
  • Le repo est votre filet de sécurité pendant l'atelier.