Lärarguide · Lektion 6 av 8

State management & DI

Mål: studenten väljer rätt livstid och kan dela tillstånd mellan komponenter. Detta är troligen kursens svåraste lektion — räkna med fler frågor.

V6
Vecka
2,5 h
Total tid
~55 min
Teori
~65 min
Workshop
Studentmaterial 06-state-di.html
Kompletterande resurser

Lektionens mål

Agenda (150 min)

0:00
Check-in + frågor om examinationen.
0:15
Teori: DI på 10 min — Singleton/Scoped/Transient.
0:30
Teori: Livstider i Blazor Server vs WASM (tabell + whiteboard).
0:50
Teori: Service+event-mönstret, IDisposable, CascadingValue.
1:10
Paus 15 min
1:25
Workshop: CartService med event och badge i navbar.
2:25
Avrundning + examinations-status-check.
2:30
Slut

Talartips per sektion

Singleton i Blazor Server: säg explicit att Singleton delas mellan alla användare. Det är kursens viktigaste säkerhetspoäng. Visa det med två webbläsarflikar.
Service+event-mönstret: rita på whiteboard. Komponent A muterar service → service raisar event → komponent B (subscriber) anropar StateHasChanged. Tre boxar, två pilar.
IDisposable är obligatoriskt: om man prenumererar i OnInit och inte avregistrerar i Dispose får man memory leaks och "ghost-renders". Säg det rakt ut.

Workshop — guide för läraren

  1. Skapa CartService som scoped med Items och event Action OnChange.
  2. I MainLayout: visa en badge med @CartService.Items.Count. Implementera IDisposable och prenumerera på OnChange.
  3. I en produktlista: knapp som anropar CartService.Add(product).
  4. Verifiera live att badgen uppdateras direkt utan navigering.
  5. Bonus: registrera en gång som Singleton, öppna i två flikar, visa att carten delas. Ändra tillbaka till Scoped.
public class CartService
{
  public List<Product> Items { get; } = new();
  public event Action? OnChange;

  public void Add(Product p) { Items.Add(p); OnChange?.Invoke(); }
  public void Remove(Product p) { Items.Remove(p); OnChange?.Invoke(); }
}

// Subscriber
@implements IDisposable
@inject CartService Cart

<span>🛒 @Cart.Items.Count</span>

@code {
  protected override void OnInitialized() => Cart.OnChange += StateHasChanged;
  public void Dispose() => Cart.OnChange -= StateHasChanged;
}

För snabba

  • Lägg till persistens till browserns localStorage via Blazored.LocalStorage.
  • Bygg en CascadingValue för "current theme" som påverkar flera komponenter.

För dem som behöver stöd

  • Förbered en tom CartService som de bara fyller i.
  • Många glömmer ?.Invoke() — påminn aktivt.

Vanliga frågor

Min badge uppdateras inte?
99% chans: glömt OnChange?.Invoke() i servicen, eller glömt att prenumerera i komponenten. Verifiera med en breakpoint.
Vad är skillnaden mellan Scoped i Server och WASM?
Server: scoped = per SignalR-circuit (ungefär per användarsession). WASM: scoped = per applikations­instans = i praktiken samma som Singleton.
Måste jag verkligen avregistrera i Dispose?
Ja. Annars hålls komponenten kvar i minnet och kan triggers ghost-rendering. I Blazor Server kan det bli minnesläckor som påverkar alla användare.
Säkerhetspoäng Kom ihåg: aldrig Singleton-tjänster med användarspecifik data i Blazor Server. En användares data syns för alla andra.
Hemuppgift Övningar + integrera service+event-mönstret i examinationsprojektet.
Förberedelse till nästa lektion Förbered en lista över gratis-API:er (Open-Meteo, JSONPlaceholder, PokeAPI) att välja från för workshopen.

← L5 L7 — API & Auth →