Webbserverprogrammering 1 · område 4 · lektion 26–27
Livstider och tillstånd
Sju övningar om hur länge ett objekt lever och var data hamnar. Fyra om livstiderna, tre om tillstånd. De hör ihop: valet av livstid är ett beslut om vem som ser vilken data.
Två genomgångar ligger bakom den här sidan. Räkna med tre timmar för båda:
- Lektion 26 – läs guidens steg 8 till 10 och bygg livstidsdemot. Kör det på riktigt: ladda om flera gånger och öppna ett privat fönster. Tabellen betyder ingenting förrän du sett siffrorna röra sig.
- Lös övning 63 till 66.
- Lektion 27 – läs steg 11 till 14. HTTP som tillståndslöst, cookien, sessionen och formuläret.
- Lös övning 67 till 69.
Öppna webbläsarens utvecklarverktyg (F12) och leta upp fliken där cookies listas innan du börjar. Sessionen syns bara där.
De tre livstiderna
Tre rader i Program.cs, tre helt olika beteenden:
builder.Services.AddTransient<ITransientRaknare, Raknare>();
builder.Services.AddScoped<IScopedRaknare, Raknare>();
builder.Services.AddSingleton<ISingletonRaknare, Raknare>();
| Livstid | Ett objekt per… | Lever tills | Används till |
|---|---|---|---|
| transient | varje gång någon frågar | direkt efter användningen | Små, tillståndslösa hjälpare |
| scoped | förfrågan | svaret är skickat | Nästan allt. Förvalet |
| singleton | server | servern startas om | Sådant som är lika för alla: inställningar, cachning |
Det är den vanligaste missuppfattningen i hela området, och den är lätt att få eftersom ordet låter som något större än det är.
Vid statisk serverrendering är ett scope en förfrågan. Laddar du om sidan är det ett nytt scope och ett nytt objekt. En lista i ett fält i en scoped tjänst är alltså tom igen vid nästa sidvisning – inte för att något är trasigt, utan för att objektet är ett annat.
Vill du att något ska följa besökaren mellan sidvisningar räcker inte livstiden. Då behövs session, och det är övning 67 och 68.
63. Transient
Lätt · tränar: AddTransient
Gör en tjänst IOvning63 med en egenskap int Nummer som
sätts i konstruktorn ur en statisk räknare. Registrera den som
AddTransient.
Injicera den två gånger på samma sida, med olika namn, och visa båda numren.
Klart när: de två numren är olika.
64. Scoped
Medel · tränar: AddScoped och vad en förfrågan omfattar
Registrera samma klass som AddScoped under ett andra gränssnitt.
Visa båda numren på sidan.
Ladda om tre gånger och skriv ned siffrorna.
Klart när: de två numren är lika på sidan, och båda ändras vid varje omladdning.
65. Singleton
Medel · tränar: AddSingleton och vad "delad" betyder
Registrera samma klass en tredje gång som AddSingleton. Ladda om
fem gånger. Öppna sedan sidan i ett privat fönster.
Klart när: numret är detsamma alla gånger, också i det privata fönstret, och du kan säga vad det betyder att två besökare fick samma objekt.
66. Fel livstid
Svår · tränar: felet som uppstår när livstider blandas
Gör en tjänst registrerad som AddSingleton som injicerar en tjänst
registrerad som AddScoped i sin konstruktor. Starta servern.
Klart när: du kan skriva av felmeddelandet och förklara varför det är ett fel – alltså vad som hade gått sönder om ramverket tillåtit det.
Bygget går igenom utan en varning. Servern startar inte. Det är en tidpunkt du inte mött förut, och den är hela poängen med övningen – fel 5 på felsökningssidan är samma sak med meddelandet utskrivet.
Tillstånd: fyra ställen att lägga data
HTTP minns ingenting. Varje förfrågan är den första servern hört av besökaren, och allt som ska överleva måste lagras någonstans med avsikt.
| Var | Vem ser det | Hur länge | Passar för |
|---|---|---|---|
| Ett fält i en scoped tjänst | ingen efter svaret | en förfrågan | Mellanresultat under renderingen |
| Ett fält i en singleton | alla besökare | tills servern startas om | Sådant som ska vara lika för alla |
| Session | en besökare | 30 min inaktivitet, eller tills webbläsaren stängs | Varukorg, visningslista, flerstegsblankett |
| Cookie | en webbläsare | det du bestämmer | Små val: språk, mörkt läge. Nyckeln till sessionen |
Sessionen ligger på servern. Cookien innehåller bara nyckeln till den – inte innehållet. Det är skillnaden som frågan om scoped, singleton och cookie i bör-kraven handlar om.
Fyra rader slår på sessionen, och tre av dem är fällor:
builder.Services.AddHttpContextAccessor();
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession();
app.UseSession();
Glöms cachen startar inte servern. Glöms
AddHttpContextAccessor når tjänsten inte förfrågan. Glöms
app.UseSession() svarar sidan 500 med
Session has not been configured for this application or request.
67. Ett värde i session
Lätt · tränar: ISession, SetString, GetString
Gör en sida som räknar hur många gånger du har besökt den, med värdet i session.
Du behöver AddDistributedMemoryCache, AddSession,
AddHttpContextAccessor och app.UseSession().
Klart när: siffran ökar när du laddar om, och börjar om på 1 i ett privat fönster.
68. En lista i session
Medel · tränar: att lagra flera värden i text
Gör en tjänst som håller en lista med heltal i session. Lagra dem som
"1,4,6" och tolka tillbaka med int.TryParse.
Sidan ska kunna lägga till ett tal med ett
<form method="post"> och visa listan.
Klart när: listan växer över flera sidvisningar och är tom i ett privat fönster.
Därför blir listan strängen "1,4,6" och inte en
List<int>. Samma sak i Filmarkivet: bara id:n sparas, aldrig
hela filmer. Sessionen ska vara liten, och posten kan alltid hämtas ur tjänsten
på nytt när den ska visas.
Knappen ska sitta i ett <form method="post"> med
@formname, @onsubmit och
<AntiforgeryToken />. Ett @onclick gör
ingenting alls här, precis som i område 3.
69. Vad hade hänt med singleton?
Svår · tränar: att resonera om delat tillstånd
Registrera tjänsten från övning 68 som AddSingleton i stället, och
håll listan i ett vanligt fält – inte i session.
Öppna sidan i två olika webbläsare, eller ett vanligt och ett privat fönster. Lägg till ett tal i den ena.
Klart när: du kan beskriva vad du såg och varför det är allvarligt. Ändra sedan tillbaka.
Koden bygger. Servern startar. Sidan fungerar. Ändå är det ett av de värsta fel du kan göra i det här området, för det syns bara när två personer använder sajten samtidigt – vilket aldrig händer när du testar ensam på din egen dator.
Det är därför kontrollen i privat fönster står som ett eget krav i inlämningen. Tio sekunder, och skillnaden mellan att tro och att veta.
Avprickning
Kryssen sparas i din webbläsare.
Lösta övningar i det här temat
Övning 68 är den som återkommer direkt i inlämningen – din samling är samma sak med en annan datatyp. Övning 65 och 69 är de två som provet frågar om.