DejaClient

Der gemeinsame Query-Cache: ein Register von Einträgen, adressiert über QueryKey, dazu Invalidierung, manuelle Lese-/Schreibzugriffe, Defaults pro Präfix und Verdrängung inaktiver Einträge.

public sealed class DejaClient : IDisposable

Registrierung#

AddDeja (extension)#

public static IServiceCollection AddDeja(this IServiceCollection services, Action<DejaOptions>? configure = null)

Registriert DejaOptions (Singleton) und DejaClient (Scoped). Scoped ist die einzig korrekte Lifetime für beide Hosting-Modelle: pro Browser-Tab auf WebAssembly, pro User-Circuit auf Blazor Server — ein Singleton auf dem Server würde die gecachten API-Antworten eines Users mit allen anderen Usern teilen. „Optimiere“ das nicht zu einem Singleton.

DejaClient(DejaOptions?)#

public DejaClient(DejaOptions? options = null)

Erstellt einen eigenständigen Client (z. B. für Tests), optional mit abweichenden Optionen, und startet die Verdrängungsschleife.

Lesen#

GetData<T>#

public T? GetData<T>(QueryKey key)

Die gecachten Daten unter key, oder default, wenn der Key fehlt, noch keine Daten hat oder mit einem anderen T gespeichert wurde.

TryGetData<T>#

public bool TryGetData<T>(QueryKey key, out T? data)

Liest die gecachten Daten unter key. Gibt false zurück, wenn der Key fehlt oder keine Daten hat. Auch ein Key, der mit einem anderen T gespeichert wurde, liefert false, statt zu werfen — das bedeutet fast immer, dass zwei Aufrufstellen sich über die Form des Keys uneinig sind, und wird als Warnung auf Debug-Level gemeldet.

GetState#

public CacheEntryState? GetState(QueryKey key)

Ein schreibgeschützter Schnappschuss des Eintrags unter key — Vorhandensein von Daten, Fetch-Flag, Invalidierung, Subscriber-Anzahl, Zeitstempel — oder null, wenn der Eintrag fehlt. Die Werte sind zum Zeitpunkt des Aufrufs in sich konsistent und aktualisieren sich danach nicht mehr. Die Cache-Inspektoren dieser Seite pollen ihn.

Schreiben#

SetData<T> (value)#

public void SetData<T>(QueryKey key, T data)

Schreibt data unter key (und erstellt den Eintrag, falls er fehlt) und benachrichtigt jede abonnierte Query. Die manuelle Alternative zur Invalidierung, wenn der neue Wert bereits bekannt ist — z. B. um das Ergebnis einer Mutation an eine gecachte Liste anzuhängen. Wirft InvalidOperationException, wenn der Key Daten eines anderen Typs hält.

SetData<T> (updater)#

public void SetData<T>(QueryKey key, Func<T?, T> updater)

Transformiert den gecachten Wert unter key: updater erhält die aktuellen Daten (oder default, wenn keine vorhanden sind) und gibt den neuen Wert zurück. Der Baustein des Patterns Optimistisches Schreiben.

Invalidierung und Refetch#

InvalidateAsync#

public Task InvalidateAsync(QueryKey key, InvalidateOptions? options = null)

Markiert jeden Eintrag, der auf key passt, als stale — per Präfix, sofern nicht InvalidateOptions.Exact — und lädt gemäß InvalidateOptions.RefetchType neu: Standardmäßig refetchen Einträge mit aktiven Subscribern im Hintergrund (vorhandene Daten bleiben auf dem Bildschirm, kein Lade-Flackern), während Einträge ohne Subscriber markiert bleiben und neu laden, sobald die nächste Komponente auf ihnen mountet. Der zurückgegebene Task ist abgeschlossen, sobald die angestoßenen Refetches beendet sind.

InvalidateAllAsync#

public Task InvalidateAllAsync()

Invalidiert jeden Eintrag im Cache; aktive Einträge refetchen im Hintergrund.

RefetchAsync#

public Task RefetchAsync(QueryKey key, QueryFilter? filter = null)

Lädt jeden Eintrag neu, der auf key passt und eine Fetch-Funktion hat — unabhängig davon, ob er stale ist. Fehler werden auf den Einträgen vermerkt, nicht geworfen.

Entfernen#

Remove#

public void Remove(QueryKey key, QueryFilter? filter = null)

Entfernt jeden Eintrag, der auf key passt, und bricht laufende Fetches ab. Abonnierte Queries rendern weiterhin ihre letzten Daten; ihr nächstes Execute startet mit einem leeren Eintrag.

Clear#

public void Clear()

Entfernt jeden Eintrag und bricht laufende Fetches ab.

Defaults und Lebenszyklus#

SetDefaults#

public void SetDefaults(QueryKey prefix, QueryDefaults defaults)

Registriert Defaults für jeden Key, der mit prefix beginnt, und ersetzt dabei frühere Defaults für dasselbe Präfix. Vorrang, das Spezifischste gewinnt: Wert pro Query > längstes passendes Präfix > DejaOptions — die Reihenfolge der Registrierung spielt keine Rolle.

Dispose#

public void Dispose()

Stoppt den Verdrängungs-Timer und verwirft jeden Eintrag; wird von der DI aufgerufen, wenn der Scope endet.

Verdrängungsverhalten#

  • Einträge mit aktiven Subscribern werden nie verdrängt.
  • Ein Eintrag ohne Subscriber wird verworfen, sobald seine Cache-Zeit abgelaufen ist (geprüft alle EvictionInterval).
  • Ist MaxEntries gesetzt, werden beim Überschreiten der Grenze zuerst die am längsten nicht genutzten Einträge ohne Subscriber verdrängt; der Cache darf die Grenze überschreiten, solange alles darin auf dem Bildschirm ist.
  • Eine Query gegen einen Key auszuführen, der bereits Daten eines anderen Typs hält, wirft — wenn zwei Aufrufstellen sich über die Form eines Keys uneinig sind, ist das ein Bug, den stilles Ersetzen verschleiern würde.