Arkitekturdiagram

Ett arkitekturdiagram visar vilka delar ett system består av och hur de hänger ihop — klient, API, databas, externa tjänster. Det finns flera sorter, från en snabb skiss med rutor och pilar till UML-diagram med strikta regler. Den här sidan samlar de vanligaste och fokuserar på C4-modellen, som är det mest användbara sättet att rita arkitektur i en .NET-lösning idag.

När du läst detta ska du kunna

  • Namnge delarna i ett C4-diagram: person, mjukvarusystem, container, komponent och relation
  • Förklara C4-modellens fyra nivåer som en zoom från systemkontext ner till kod
  • Känna igen ett blockdiagram, ett UML-komponentdiagram, ett paketdiagram och ett driftsättningsdiagram
  • Välja rätt diagram beroende på vem som ska läsa det och vad de vill veta

Vad används det till?

  • Få överblick — vilka delar finns, och vilka pratar med varandra?
  • Introducera nya i teamet — en bild säger mer än tio README-stycken
  • Fatta beslut — ska e-posten skickas från API:t eller från en egen tjänst? Rita båda och jämför
  • Planera drift — vad körs var, och vilka portar måste vara öppna?
  • Dokumentera inför kodgranskning, examensarbete eller överlämning till kund

Delarna och vad de heter

Här är en bokningsapp ritad som ett C4-diagram på nivå 2 (container). Kunden bokar tider i en webbklient, som anropar ett ASP.NET Core-API. API:t sparar i en databas och skickar bekräftelser via en extern e-posttjänst.

C4-containerdiagram för en bokningsapp med namngivna delar: person, relation med beskrivning och teknik, mjukvarusystem som streckad gräns, containrar för webbklient, API och databas, samt ett externt system för e-post Kund [Person] Bokar tid [HTTPS] Webbklient [Container: Blazor] Anropar API [JSON/HTTPS] Boknings-API [Container: ASP.NET Core] Lagrar data [EF Core] Databas [Container: SQL Server] Bokningssystem [Mjukvarusystem] E-posttjänst [Externt system] Skickar mejl [SMTP] Person Relation Teknik [ ] Mjukvarusystem Container Externt system
DelHur den ritasVad den betyder
PersonGubbe eller rundad ruta, märkt [Person]En människa som använder systemet — kund, admin, personal
MjukvarusystemRuta (nivå 1) eller streckad gräns runt containrar (nivå 2)Det system du bygger, sett som en helhet med ett namn
Externt systemGrå ruta utanför gränsenEtt system någon annan äger: e-post, betalning, BankID
ContainerRuta inne i systemgränsen, märkt [Container: teknik]Något som körs eller lagrar data separat: en webbapp, ett API, en databas, en kö. Inte en Docker-container (även om det ofta blir en)
KomponentRuta inne i en container (nivå 3)En grupp kod med ett tydligt ansvar: en controller, en service, ett repository
RelationPil med en beskrivning (“Bokar tid”)Vem som använder eller anropar vem, och varför
TeknikText i [hakparenteser] på ruta eller pilVilken teknik som används: [HTTPS], [EF Core], [SMTP]

Två regler gör C4-diagram läsbara: varje pil har en beskrivning, och varje ruta säger vad den är ([Person], [Container: …]). En pil utan text tvingar läsaren att gissa.

C4-modellen — fyra zoomnivåer

C4 (av Simon Brown) står för Context, Containers, Components, Code. Tänk på det som en karttjänst: först ser du hela landet, sedan zoomar du in på en stad, en gata och till sist ett hus. Varje nivå zoomar in på en ruta från nivån ovanför.

C4-modellens fyra nivåer som en zoom: systemkontext, container, komponent och kod, där en markerad ruta på varje nivå förstoras på nästa Nivå 1Systemkontext Nivå 2Container Nivå 3Komponent Nivå 4Kod System Externt Webb API Databas Controller Service Repository BokningService - repo + Boka() + Avboka() + HämtaLediga() Vem använder systemet? Vilka delar körs? Vad finns i en del? Hur ser koden ut?
NivåVisarFrågan den svarar påVem läser den
1 SystemkontextSystemet som en ruta, plus personer och externa system runt omkringVad är det här, vem använder det, vad är det beroende av?Alla — även kund och beställare
2 ContainerDet som körs separat: webbklient, API, databasVilka delar driftsätts, och hur pratar de?Utvecklare, drift, arkitekt
3 KomponentInnehållet i en containerHur är API:t uppdelat i ansvarsområden?Utvecklarna i teamet
4 KodKlasser och interface i en komponentHur är just den här delen implementerad?Den som ska ändra koden

Nivå 1 och 2 är de du nästan alltid ritar. Nivå 3 ritar du för de containrar som är stora eller svåra. Nivå 4 ritar du sällan för hand — det är i praktiken ett klassdiagram, och koden själv (eller verktyget som genererar diagrammet ur den) är ofta bättre.

Exempel — bokningsappens API på nivå 3

Vi zoomar in på containern Boknings-API. Inuti finns komponenterna som tar emot anropet, utför logiken, sparar och skickar e-post. Rutorna utanför den streckade gränsen är andra containrar och system — de är med för att visa vart pilarna går.

C4-komponentdiagram för Boknings-API: BokningController anropar BokningService, som sparar via BokningRepository till databasen och skickar bekräftelse via EpostKlient till en extern e-posttjänst Webbklient [Container: Blazor] Gör bokning [JSON/HTTPS] Boknings-API [Container: ASP.NET Core] BokningController [Komponent: Controller] anropar BokningService [Komponent: Service] sparar bokning skickar bekräftelse BokningRepository [Komponent: EF Core] EpostKlient [Komponent: SMTP-klient] Läser/skriver [EF Core, SQL] Databas [Container: SQL Server] Skickar mejl [SMTP] E-posttjänst [Externt system]

Varje komponent blir i praktiken en klass (eller en liten grupp klasser) med ett interface, och pilarna blir beroenden som du kopplar ihop med dependency injection:

// Program.cs — varje rad registrerar en komponent från diagrammet
builder.Services.AddDbContext<BokningContext>(o =>
o.UseSqlServer(builder.Configuration.GetConnectionString("Bokning")));
builder.Services.AddScoped<IBokningRepository, BokningRepository>(); // sparar bokning
builder.Services.AddScoped<IEpostKlient, SmtpEpostKlient>(); // skickar bekräftelse
builder.Services.AddScoped<BokningService>();
builder.Services.AddControllers();
public class BokningService
{
private readonly IBokningRepository _repo;
private readonly IEpostKlient _epost;
// Pilarna i diagrammet = det som skickas in i konstruktorn
public BokningService(IBokningRepository repo, IEpostKlient epost)
{
_repo = repo;
_epost = epost;
}
public async Task<Bokning> BokaAsync(BokningRequest request)
{
var bokning = new Bokning(request.KundEpost, request.Tid);
await _repo.SparaAsync(bokning); // → BokningRepository
await _epost.SkickaAsync(bokning.KundEpost, "Din bokning är klar"); // → EpostKlient
return bokning;
}
}

Lägg märke till att pilarna går från den som använder till den som används. BokningService känner till IBokningRepository — inte tvärtom. Läs mer om varför det är bra i Repository och dependency inversion.

Andra diagram för systemets uppbyggnad

Blockdiagram

Det enklaste: rutor och pilar, inga regler. Perfekt på whiteboarden eller i en första diskussion, men eftersom det saknar regler betyder en pil olika saker för olika personer. Så fort skissen ska sparas — gör den till ett C4-diagram genom att lägga till beskrivning och teknik.

Blockdiagram för bokningsappen: Användare, Bokningsapp, Databas och E-post som rutor med pilar emellan, utan beskrivningar Användare Bokningsapp Databas E-post

UML-komponentdiagram

UML:s variant av C4 nivå 2–3. Det som är speciellt är gränssnitten: en komponent tillhandahåller ett gränssnitt (en “boll”, lollipop) och en annan kräver det (en “sockel” som griper om bollen). Det visar exakt vilket kontrakt delarna pratar genom — i C# motsvarar det ett interface.

UML-komponentdiagram: Webbklient kräver gränssnittet IBokningar som Boknings-API tillhandahåller, och Boknings-API kräver IEpost som E-posttjänst tillhandahåller, ritat med boll och sockel «component» Webbklient «component» Boknings-API «component» E-posttjänst IBokningar IEpost Krävt gränssnitt (sockel) Tillhandahållet gränssnitt (boll) Komponent

I C# blir det: Boknings-API tillhandahåller IBokningar (klassen implementerar interfacet), och Webbklient kräver det (tar emot interfacet i konstruktorn). Så länge kontraktet är detsamma kan du byta ut vad som finns bakom bollen.

Paketdiagram — projekt och namespaces i en .NET-lösning

Ett paketdiagram visar hur koden är organiserad: vilka projekt eller namespaces som finns och vilka som beror på vilka. Paketet ritas som en mapp med flik. Den streckade pilen betyder “använder” — i .NET blir det en projektreferens.

Paketdiagram för en .NET-lösning: Bokning.Api beror på Bokning.Infrastructure och Bokning.Core, Bokning.Infrastructure beror på Bokning.Core, och Bokning.Tests beror på Bokning.Core Bokning.Api Controllers, Program.cs Bokning.Tests xUnit-tester Bokning.Infrastructure DbContext, repositories Bokning.Core Bokning, IBokningRepository Flik Paket (projekt) Beroende Innehåll

Diagrammet motsvarar en lösning som ser ut så här:

Bokning.sln
├── Bokning.Api/ → refererar Bokning.Core och Bokning.Infrastructure
├── Bokning.Core/ → refererar ingenting (domänen står för sig själv)
├── Bokning.Infrastructure/ → refererar Bokning.Core
└── Bokning.Tests/ → refererar Bokning.Core
Terminal window
dotnet add Bokning.Api reference Bokning.Core Bokning.Infrastructure
dotnet add Bokning.Infrastructure reference Bokning.Core
dotnet add Bokning.Tests reference Bokning.Core

Det viktiga paketdiagrammet visar: alla pilar pekar in mot Core, ingen pil går ut från den. Då kan du testa domänlogiken utan databas, och byta databas utan att röra domänen. Ser du en pil från Core till Infrastructure har något gått snett.

Driftsättningsdiagram (deployment)

Ett driftsättningsdiagram visar var saker körs: vilka maskiner (noder) som finns, vad som är installerat på dem (artefakter) och hur de är förbundna. Det är diagrammet drift och moln-folk vill ha.

Driftsättningsdiagram: noden Kundens dator med webbläsare, noden Webbserver med en .NET-runtime som kör artefakten Bokning.Api.dll, och noden Databasserver med SQL Server, förbundna via HTTPS och TCP 1433 Kundens dator «device» Webbläsare Webbserver «node» Linux-VM «executionEnvironment» .NET-runtime «artifact» Bokning.Api.dll Databasserver «node» SQL Server HTTPS TCP 1433 Nod Exekveringsmiljö Artefakt Kommunikationsväg
DelHur den ritasVad den betyder
Nod3D-lådaNågot som kan köra kod: en fysisk maskin, en VM, en mobil («device»)
ExekveringsmiljöLåda inuti en nodMjukvara som kör din kod: .NET-runtime, en webbläsare, en container-runtime
ArtefaktRektangel med «artifact» och dokumentikonEn fil som driftsätts: Bokning.Api.dll, en Docker-image, en .zip
KommunikationsvägLinje mellan noder, med protokoll eller portHur noderna pratar: HTTPS, TCP 1433

Hur noderna kopplas ihop i nätverket — brandväggar, subnät, lastbalanserare — ritar du hellre i ett nätverksdiagram.

När ska du välja vilket?

Du vill visa…VäljFör vem
En snabb idé på whiteboardenBlockdiagramDig själv och teamet, just nu
Vad systemet är och vem som använder detC4 nivå 1 — systemkontextKund, beställare, nya i teamet
Vilka delar som körs och hur de pratarC4 nivå 2 — containerUtvecklare, drift
Hur en del är uppbyggd inutiC4 nivå 3 — komponentUtvecklarna
Exakt vilka kontrakt (interface) delar pratar genomUML-komponentdiagramUtvecklare, arkitekt
Hur lösningen är uppdelad i projekt och vilka referenser som är tillåtnaPaketdiagramUtvecklarna
Vad som körs på vilken maskinDriftsättningsdiagramDrift, moln, DevOps

Och när arkitekturdiagram inte är rätt verktyg:

Välj arkitekturdiagram när…Välj något annat när…
Du vill visa vilka delar som finnsDu vill visa i vilken ordning delarna pratar → sekvensdiagram
Du beskriver hela systemet eller en containerDu beskriver klasser och metoder i detalj → klassdiagram
Du vill visa vilka system som utbyter dataDu vill visa vilken data som flödar och vart den lagras → dataflödesdiagram
Du visar vad som körs varDu visar IP-adresser, subnät och brandväggar → nätverksdiagram

Vanliga misstag

  • Pilar utan text. “API → Databas” kan betyda läser, skriver, synkar eller övervakar. Skriv vad som händer och med vilken teknik.
  • Blandade nivåer. En ruta för “Webbklient” bredvid en ruta för “BokningService” — en container och en komponent i samma bild. Håll dig till en nivå per diagram.
  • Allt i ett diagram. Ett diagram med 30 rutor blir en tapet ingen läser. Zooma istället: nivå 1, sedan nivå 2, sedan nivå 3 för det som är svårt.
  • “Container” = Docker. I C4 betyder container något som körs eller lagrar data separat. En databas är en container även om den inte körs i Docker.
  • Ingen förklaring av symbolerna. Lägg till en liten teckenförklaring om du använder färger eller former som inte är självklara.

Övning

Rita bokningsappen på nivå 1 (systemkontext): en ruta för Bokningssystem, personerna Kund och Personal, och de externa systemen E-posttjänst och Betaltjänst. Skriv en beskrivning på varje pil.

Rita sedan ett paketdiagram för ett av dina egna projekt. Pekar alla pilar åt rätt håll — in mot domänen? Finns det någon referens du skulle vilja ta bort?

TL;DR

BegreppVad det är
BlockdiagramRutor och pilar utan regler — bra skiss, dålig dokumentation
C4Fyra zoomnivåer: systemkontext → container → komponent → kod
Container (C4)Något som körs eller lagrar data separat — webbapp, API, databas
Relation (C4)Pil med beskrivning och [teknik]
UML-komponentdiagramKomponenter och gränssnitt (boll = tillhandahåller, sockel = kräver)
PaketdiagramProjekt/namespaces och deras beroenden
DriftsättningsdiagramNoder, exekveringsmiljöer och artefakter — vad körs var