Alt du må vite om .NET 6: - Litt kronglete historikk

Tobias gir deg 8 spennende nyheter - og knuser et par myter.

Tobias Moe Thorstensen er over snittet opptatt av .NET, og gir deg alt du må vite om .NET 6.
Tobias Moe Thorstensen er over snittet opptatt av .NET, og gir deg alt du må vite om .NET 6. Vis mer

Det er snart november igjen, og det betyr en ny versjon av .NET.

Denne gangen lanserer Microsoft versjon 6 av den populære utviklingsplattformen. Før vi dykker ned i hva som er nytt i denne versjonen, skal vi knuse noen myter om .NET og greie ut om den litt kronglete versjoneringshistorikken til plattformen.

Mange forbinder nok .NET med utvikling rettet mot operativsystemet Windows. Noen oppfatter også .NET som et programmeringsspråk.

La oss få klarhet i dette.

Hva er egentlig .NET?

.NET en utviklingsplattform og ikke et språk.

Språkene som støttes av plattformen er VB, C# og den funksjonelle varianten F#. Språkene blir oversatt til Intermediate Language og kjøres i Common Language Runtime også kalt CLR. Har du erfaring fra Java-verden og språk som for eksempel Kotlin Scala, virker dette kanskje kjent - CLR er nemlig ekvivalenten til JVM.

Når .NET omtales som plattformen for utvikling av Windows-applikasjoner, refereres det til .NET Framework. Den første versjonen av .NET Framework ble lansert i 2002 og den siste, versjon 4.8, i 2019.

«For å ikke gjøre forvirringen komplett ved å blande .NET 4 med .NET Framework 4, valgte Microsoft å hoppe rett til .NET 5.»

Da .NET Core ble lansert i 2016 ble det mulig å kompilere og kjøre .NET applikasjoner på Linux -og Unix-baserte systemer. I november 2020 var det duket for en ny, stor versjon, men Microsoft måtte bestemme seg for navn og versjon. Skulle de kalle den nye versjonen for .NET Core 4 eller rett og slett droppe «Core» i navnet? Skulle navnet være .NET 4?

For å ikke gjøre forvirringen komplett ved å blande .NET 4 med .NET Framework 4, valgte Microsoft å hoppe rett til .NET 5. Denne versjonen representerte det neste store steget mot en enhetlig plattform som lar utviklere skrive programvare rettet mot web, desktop, sky, mobile plattformer, Xbox og IoT-dingser.

I årene som kommer vil vi ikke høre så mye om .NET Framework og .NET Core da disse plattformene tilhører fortiden. Microsoft har planlagt at det skal komme nye versjoner av .NET plattformen hvert år, hvor LTS varianten slippes hver November. Sammen med en ny versjon av plattformen vil det også bli lansert nye versjoner av programmeringsspråkene C# og F#. Neste utgivelse er da .NET 6, C# 10 og F# 6 som lanseres November 2021.

Med .NET 6 og C# 10 introduserer Microsoft en del nye konsepter, rammeverk og verktøy, samt ytelsesforbedringer på hele plattformen. Det er planlagt at lanseringen skjer på dotnetconf den 9. November 2021, men vi har hatt muligheten til å eksperimentere og teste ut Preview versjoner siden Februar 2021. Sammen med .NET 6 slippes også C# 10.

Resten av denne artikkelen kommer til å legge vekt på ny funksjonalitet som artikkelforfatteren finner mest interessante.

#1: Top level statements & Minimal APIs

Teamet bak .NET har innsett at det er en del boilerplate kode og seremoni som må til for å utvikle .NET applikasjoner. Skal man utvikle en helt enkel applikasjon som bare spytter ut «Hello, World!» har det i tidligere versjoner av .NET sett slik ut:


using System;
using System.Collections.Generic;
using System.Linq;

namespace MyApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

Det er hele 14 kodelinjer. I .NET 6 vil standardmalen når du skriver dotnet new console se slik ut:

Console.WriteLine("Hello World!");

Denne printer ut, kanskje ikke helt overraskende, «Hello World!» i terminalen når man kjører applikasjonen. Det er ikke spesielt revolusjonerende, men intensjonen bak en slik endring blir enda tydeligere når man skal opprette et ASP.NET prosjekt for å utvikle programvare for web, f.eks REST APIer eller Blazor applikasjoner. Ønsker du å lese mer om frontendutvikling i .NET har jeg skrevet om det tidligere.

Tradisjonelt sett har en slik løsning bestått av klassene Program.cs og Startup.cs, hvor førstnevnte har vært applikasjonens inngangspunkt med Main-metoden og Startup.cs innholdt kode for å blant annet konfigurere opp infrastruktur og avhengigheter. I .NET 6 blir dette enda lettere. Heretter holder det med Program.cs og et helt enkelt API med en HTTP GET metode ser nå slik ut:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

#2: Package Validation Tooling

Økosystemet rundt .NET vokser stadig og antall offentlig tilgjengelige pakker publisert på pakkehåndteringsverktøyet NuGet har i skrivende stund rundet 3 670 000 versjoner fordelt på 276 000 unike pakker. Det er et lite stykke igjen opp til npm, men utfordringen rundt breaking changes og kompabilitet er like fullt en utfordring. I Preview 5 av .NET 6 ble det lansert et verktøy som skal hjelpe utviklere til å fange opp denne type feil når koden bygges eller prosjektet blir pakket som en NuGet-pakke.

Dette verktøyet er det mange som kommer til å dra nytte av, både som utviklere av bibliotekskode og konsumenter. Jeg anbefaler å lese mer på bloggen til Microsoft hvor de går i detalj og viser scenarioer hvor dette verktøyet kan være til hjelp.

#3: .NET Multi-Platform App UI (MAUI)

MAUI er Microsoft sitt svar på «La meg skrive GUI-kode og la min applikasjon kjøre på iOS, macOS, Android og Windows». Det virker kanskje kjent? Du har sikkert hørt om Xamarin. MAUI er bygd på toppen av Xamarin og blir inkludert som en del av .NET plattformen. I utgangspunktet skulle MAUI LTS blitt inkludert i .NET 6, men av ulike årsaker har ikke teamet rukket deadlinen. Jeg antar derfor at MAUI LTS blir lansert som en del av .NET 7 i November 2022. Ønsker du derimot å prøve ut MAUI kan du eksperimentere med Preview versjoner.

#4: Støtte for HTTP 3

HTTP i sin absolutt aller enkleste form består av å åpne en TCP-tilkobling til en motpart, sende noe data og motta et svar tilbake i klartekst. TLS tilfører et lag med sikkerhet, men ettersom HTTP 1.1 kun kan serve en forespørsel per tilkobling vil TLS handshaken måtte finne sted ved hver tilkobling.

HTTP 2 introduserte konseptet med at flere forespørsler kunne dele tilkobling. Som et resultat av dette trengte kun TLS handshanken å finne sted én gang. Ulempen med dette er at trafikk blir sendt over en tilkobling kan man oppleve pakketap og at etterfølgende forespørsler blir blokkert i påvent av at pakken blir «gjenfunnet». Dette blir omtalt som «Head of line blocking problem».

HTTP 3 løser overnevnte problem ved å bruke en ny underliggende protokoll kalt QUIC som er basert på UDP og som har TLS innebygd. Hver pakke blir kryptert fremfor tilkoblingen. Dette gjør at man unngår «Head of line blocking» som i HTTP 2. En annen stor fordel med HTTP 3 er at en QUIC-tilkobling er uavhengig av IP-adressen til enheten, slik at mobileenheter kan bytte mellom trådløse nettverk og 4/5G uten å avbryte ned -eller opplastning av data.

«Problemet med using-statements er at det kan bli mange av dem i en fil.»

RFCen til HTTP 3 er enda i kladdemodus og ikke offisielt lansert selv om de fleste nettlesere har støtte for denne protokollen. Støtte for HTTP 3 blir inkludert i .NET 6 som en preview feature.

#5: Nye typer for å representere dato og tid

Siden den spede begynnelse har .NET utviklere benyttet seg av typen DateTime for å representere dato og tid. Det har aldri tidligere vært en separasjon på disse to enhetene. Ønsket man å kun spesifisere en dato, ville klokkeslettet bli satt til 00:00:00. Med .NET 6 vil man nå kunne benytte seg av enten dato og tid, og selvfølgelig DateTime som tidligere.

De nye struct-typene i .NET 6 heter DateOnly og TimeOnly og kommer med en rekke hendige metoder som f.eks DateOnly.DayOfWeek og TimeOnly.IsBetween(time1, time2);

#6: Global using statements

Når man skriver .NET applikasjoner med C# er man avhengig av biblioteker. Pakkene kommer enten fra Base Class Libraries, altså fra .NET plattformen, eller andre utviklere som publiserer sine pakker på .NET sin pakkehåndteringsplattform, NuGet. Man deklarerer bruken av pakkene i toppen av hver fil som using-statements. Ekvivalenten som brukes i java kalles for import-statements.

using System.Threading.Tasks;
					
public class Program
{
public static async Task Main()
   	{
		Console.WriteLine("Hello World");
    	}
}

Problemet med using-statements er at det kan bli mange av dem i en fil og det skapes mye boilerplate kode. Med C# 10 kan man lage en egen fil som definerer alle avhengigheter for et prosjekt. Det anbefales at man lager én fil per prosjekt. Innholdet av filen kan se slik ut:

global using System.Text.Json;
global using System.Threading.Tasks;
global using Polly;
global using FluentValidation;

#7: Record structs

C# 9 introduserte en ny type kalt records. Da denne type ble lansert ble den laget som en reference type, hvilket betyr at den blir lagret på heapen. I C# 10 kan man nå velge om en record skal være en reference type eller value type. Dette gjøres når typen deklareres:

public readonly record struct Person(string FirstName, string LastName);

Inkluderer du ikke readonly og struct i deklarasjonen vil record bli tolket som en reference type som i C# 9. Ønsker du å lese mer om Records og dens sterkheter, så skrev jeg om det da C# 9 og .NET 5 ble lansert.

#8: Utvidet støtte for Pattern matching

Pattern matching er en teknikk hvor du tester om et uttrykk oppfyller visse kriterier på en uttrykksfull og konsis måte. Pattern matching ble introdusert med C# 7 og kan på enklest mulig måte demonstreres på følgende måte:

if(input is int age && age > 30)

C# 9 introduserte det som kalles for Property Pattern Matching. Dette er en kraftfull måte å matche inneholdet av et objekt på.

public decimal GetTaxFee(Product product) => product switch
{
    { Category: { Type: "Groceries" } } => 0.25,
    _ => throw new NotSupportedException();
};

I C# 10 trenger man ikke alle krøllparantesene for å matche på inneholdet i nøstede properties. Uttrykket ovenfor kan dermed skrives slik:

public decimal GetTaxFee(Product product) => product switch
{
    { Category.Type: "Groceries" } => 0.25,
    _ => throw new NotSupportedException();
};

Sjekke ut på forhånd

.NET 6 lanseres på dotnetconf den 9. November 2021. I mellomtiden kan du laste ned release candidate versjonen fra Microsoft sine nettsider.

Benytter du deg av macOS eller en Linux distro anbefaler jeg deg å sjekke ut utviklingsverktøyene Rider eller Visual Studio Code med C# plugin installert.

Sitter du på Windows kommer du langt med Visual Studio Community Edition.

Ønsker du å være enda lengre fremme og kjører macOS kan du sjekke ut preview versjonen av Visual Studio 2022 for Mac.

Har du spørsmål kan dere finne meg på Twitter under handle @Thorstensen eller på StackOverflow.