Webblog

C# 9.0 nieuwe features – Record types (4-4)

C# 9.0 nieuwe features – Record types (4-4)

Met de komst van C# versie 9.0 zijn er heel veel waardevolle toevoegingen gedaan aan de programmeertaal en in deze Blog serie zullen we inzoomen op een aantal belangrijke nieuwe features. Al eerder behandeld in deze serie is deel 3 “Top-level statements”, we gaan nu verder met het laatste deel: “Record types”.

Om C# 9.0 te kunnen gebruiken dien je eerst de .NET 5 runtime of SDK te installeren. Ga hiervoor naar https://dotnet.microsoft.com/download. Na installatie zal C# 9.0 de standaard C# versie zijn bij elk nieuw project gebaseerd op .NET 5.

Waarom?

In deel 2 van deze serie is al gewezen op init-only setters. Op een eenvoudige manier kun je daarmee aangeven dat properties als immutable behandeld moeten worden.

Met het nieuwe keyword record krijg je als programmeur de mogelijkheid om snel en overzichtelijk een complete class immutable te maken. Je kunt dit record dan instantiëren, waarbij de data initieel wordt gezet en daarna niet meer te wijzigen is.

Dit levert je een aantal voordelen op.

Denk aan toepassing van deze record types in een multi-threaded applicatie. Omdat het object immutable is, met andere woorden niet kan worden benaderd om wijzigingen door te voeren, kan er geen race condition optreden waarbij thread 1 gegevens leest terwijl thread 2 gegevens schrijft. Je code kan worden vereenvoudigd zonder risico op deadlocks of nog erger, berekeningen met een onverwachte uitkomst.

Een ander groot voordeel van een immutable record is dat je de betrouwbaarheid van je unittesten kunt vergroten. Stel je een applicatie voor waarbij een “ouderwetse” DTO-class door diverse methodes in een keten als parameter wordt gebruikt. Wanneer de inhoud van deze class mutable is, zul je bij het schrijven van een test op één van die methodes uit moeten zoeken of er methodes bestaan die gegevens in jouw DTO kunnen wijzigen. Dit kan namelijk impact hebben op het aantal scenario’s dat je zult moeten testen.
Een immutable record maakt het onmogelijk dat gegevens worden gewijzigd, waardoor je veilig deze uitzoekklus over kunt slaan.

Hoe?

Declareren en instantiëren

C# 9.0 biedt twee mogelijkheden om een record te declareren. Het meest eenvoudig is de volgende manier, waarbij je positional arguments toepast:

Deze methode is intuïtief en overzichtelijk. De C# compiler voegt boilerplate-code zoals een constructor met parameters en een deconstructor toe zodat je direct een Object van het type Car kunt aanmaken en gebruik kan maken van enkele handige uitbreidingen. Uit de intellisense blijkt dat de aangegeven property LengthInCm gebruikt maakt van init als setter en dus inderdaad immutabel is.
Er is géén parameterloze constructor aanwezig, je bent dus verplicht om de parameters via de constructor te vertrekken.

blank

Veel controle over Racecar heb je natuurlijk niet, nuttige zaken als het inbouwen van validatie of het aangeven van een default value is zo niet mogelijk. Daarom is ook de meer klassieke ogende methode beschikbaar waardoor je bijvoorbeeld berekende properties of methodes kunt toevoegen.

blank

Vergelijken van records

Een mooie eigenschap van een record is dat het zuiver gezien een reference type is, maar dat het zich gedraagt als een value type. Dit heeft een belangrijk effect op het vergelijken van instances van records.
Bij de vergelijking wordt namelijk – net als bij een echt value type – niet gekeken of de instances naar hetzelfde object verwijzen, maar of het type en de inhoud van de record instanties overeenkomen.

De bijgaande test brengt dit mooi in beeld.
Er worden 2 aparte instanties van PersonRecord aangemaakt en vervolgens vergeleken via de ==-operator en de AreEqual methode. Met classes zijn we gewend dat dit verschillende objecten zijn en daarom verwachten we dat de test faalt. Maar omdat records zich gedragen als value types slaagt deze test.

blank

Muteren van een record

Hoewel een record immutable is, is het wel mogelijk een kopie te maken van een instantie en daarbij kleine wijzigingen aan te brengen met behulp van het keyword with op de volgende manier:

blank

Verder?

Bij het record type krijg je nog een aantal andere methodes tot je beschikking.

ToString()

Deze methode levert automatisch de inhoud van het type en alle publieke properties.

blank

Deconstructor()

De deconstructor geeft je de mogelijkheid om op de volgende manier de gegevens uit je record te verzamelen.

blank

berglerC# 9.0 nieuwe features – Record types (4-4)
Lees meer

C# 9.0 nieuwe features – Top-level Statements (3-4)

C# 9.0 nieuwe features – Top-level Statements (3-4)

Met de komst van C# versie 9.0 zijn er heel veel waardevolle toevoegingen gedaan aan de programmeertaal. In deze Blog serie zullen we inzoomen op een aantal belangrijke nieuwe features. We gaan nu verder met “Top-level Statements”.

Om C# 9.0 te kunnen gebruiken dien je eerst de .NET 5 runtime of SDK te installeren. Ga hiervoor naar https://dotnet.microsoft.com/download. Na installatie zal C# 9.0 de standaard C# versie zijn bij elk nieuw project gebaseerd op .NET 5.

Waarom?

Elke .NET assembly die uitvoerbaar is, dient een entrypoint te hebben anders heeft de applicatie geen startpunt. Dit startpunt is de welbekende Main methode. Zelfs een simpele console applicatie heeft een Main methode nodig om te kunnen functioneren.

Het requirement van zo’n Main methode maakt dat C# een ietwat minder toegankelijke programmeertaal is voor beginners. Wanneer beginners de volgende code onder ogen krijgen, kan dat best intimiderend overkomen:

blank

Het enige wat bovenstaande code moet doen is de tekst “Hello World!” tonen op het scherm, maar voordat de applicatie zover is moet er dus eerst heel veel “ceremonie” plaatsvinden:

  • using
  • namespace
  • class
  • Main methode definitie (het startpunt).

De nieuwe C# 9.0 feature “Top-level Statements” maakt deze ceremonie overbodig en dus hopelijk ook wat meer toegankelijk voor beginners!

Hoe?

De volgende code is vanaf C# 9.0 uitvoerbaar geworden op zichzelf, zonder extra code:

blank

Zoals je kan zien is deze code van alle “ceremonie” ontdaan, dus geen class definitie en geen Main methode definitie meer. Je kunt je vast voorstellen dat dit veel beter te begrijpen is voor een beginner dan de eerdere voorbeeldcode.

using statements zijn gewoon nog te gebruiken om te voorkomen dat je steeds de fully qualified type namen moet specificeren:

blank

Verder?

Ondanks dat er geen Main methode is gedefinieerd, ben je nog steeds in staat om de args parameter te gebruiken om de command-line parameters uit te kunnen lezen:

blank

Wanneer de Top-level Statements het await keyword bevatten, zal de C# compiler onderwater automatisch een async entrypoint maken:

blank

De mogelijkheid bestaat nog steeds om een int waarde terug te geven, welke aangeeft wat de zogenaamde exitcode is van je applicatie.

blank

Maar?

Bij het gebruik maken van Top Level Statements zijn er wel een tweetal beperkingen waar je rekening mee moet houden.

  • Top Level Statements kunnen slechts in één bestand onder het project aanwezig zijn.
  • In principe geen nieuwe regel, maar wanneer er Top Level Statements aanwezig zijn in een project, mogen er geen andere entrypoints bestaan.
berglerC# 9.0 nieuwe features – Top-level Statements (3-4)
Lees meer

C# 9.0 nieuwe features – Pattern Matching (2-4)

C# 9.0 nieuwe features – Pattern Matching (2-4)

Met de komst van C# versie 9.0 zijn er heel veel waardevolle toevoegingen gedaan aan de programmeertaal. In deze Blog serie zullen we inzoomen op een aantal belangrijke nieuwe features. Al eerder behandeld in deze serie is deel 1 “Init Only Setters”, we gaan nu verder met “Pattern Matching”.

Om C# 9.0 te kunnen gebruiken dien je eerst de .NET 5 runtime of SDK te installeren. Ga hiervoor naar https://dotnet.microsoft.com/download. Na installatie zal C# 9.0 de standaard C# versie zijn bij elk nieuw project gebaseerd op .NET 5.

Waarom?

De syntax van ontwikkeltalen is al sinds jaren het onderwerp van discussies tussen ontwikkelaars. Leesbaarheid, efficiëntie en flexibiliteit is slechts een selectie van de tientallen argumenten die jouw mening vormen over het al dan niet geslaagd zijn van een syntax.
Martin Fowler geeft een – zoals we van hem gewend zijn – zeer zinvolle bijdrage in deze discussie met zijn bekende uitspraak:

Any fool can write code that a computer can understand.
Good programmers write code that humans can understand.

Met die uitspraak in het achterhoofd heeft Microsoft een aantal vereenvoudigingen aan de syntax van if en switch doorgevoerd.

Deze onderdelen worden door ons veel gebruikt om complexe condities uit te werken.
Sinds C# 7.0 helpt Pattern Matching ons om de code die we opleveren beter leesbaar en dus minder foutgevoelig te maken. Ook in C# 9.0 zijn er weer enkele nieuwe mogelijkheden toegevoegd.

Hoe?

Logical pattern

Om meer complexe condities goed leesbaar te houden is het logical pattern toegevoegd aan C# 9.0. Hiermee kunnen we gebruik maken van and, or en not in onze statements, en het herhalen van de parameter waarmee vergeleken moet worden kan achterwege worden gelaten.

blank

Dit is een krachtig mechanisme dat kan worden gebruikt in if-statements zoals in bijgaand voorbeeld. De volgorde waarin de controles worden uitgevoerd is volstrekt logisch, maar in sommige gevallen zul je toch aan deze volgorde moeten wennen. Vergeet dus niet om unittests toe te voegen met voldoende testsets om er zeker van te zijn dat je functie in alle gevallen het gewenste gedrag vertoont.

Het Logical pattern komt zelfs beter tot zijn recht wanneer dit wordt gecombineerd in switch expressions, zoals we hierna zullen zien bij het Relational Pattern.

Relational pattern

In C# 8.0 zijn switch expressions toegevoegd. Hiermee was het mogelijk om direct een returnwaarde als resultaat van een aantal voorwaarden te definiëren. De syntax bevatte veel onnodige herhalingen en was daarom nog niet in alle gevallen even leesbaar, zoals het onderstaande voorbeeld illustreert.

blank

In C# 9.0 kunnen we de bovenstaande syntax verder verfijnen door gebruik te maken van het Relational pattern. Hierdoor kunnen we rechtstreeks gebruik maken van relational operators zoals < of >=. Toepassing leidt tot het volgende resultaat:

blank

In deze syntax ligt de nadruk op de logica en het resultaat, en veel minder op het achterhalen van de juiste objecten.
We zien ook dat het gebruik van het Logical Pattern ook daadwerkelijk de leesbaarheid van de code vergroot: in één oogopslag is nu duidelijk dat er een selectie gemaakt wordt voor iemand tussen de 12 en 60.

Dit voorbeeld leent zich daarnaast om de switch expression, die in C# 8.0 al is geïntroduceerd nogmaals onder de aandacht te brengen.
Bij de switch expression staat de variabele vóór het switch keyword, de switch-onderdelen case en : zijn vervangen door de bekende =>. Als laatste is de body is geen statement meer, maar een expressie.
De expression is in het onderstaand voorbeeld uitgewerkt. Hierbij zien we dat we ons niet hoeven te beperken tot property checking, ook Type checking behoort tot de mogelijkheden.

blank

Type pattern

Met het type pattern kun je met een vereenvoudigde syntax conditie checks op type en properties uitvoeren . De nieuwe schrijfwijze in C# 9.0 is compact en overzichtelijk, zoals in onderstaand voorbeeld wordt getoond.

blank

Wanneer de parameter person niet van het type PersonRecord is ontstaat er geen exception maar wordt de evaluatie van het if-statement afgebroken. In het andere geval (person is van het type PersonRecord) wordt het resultaat bepaald op basis van de property Age van person.

Wees je er in dit voorbeeld goed van bewust dat deze code géén NullReferenceException oplevert wanneer de parameter person null is.

Verder?

Veel van onze logica in onze applicaties is vormgegeven door implementaties van if-then-else en switch statements. Na verloop van tijd kunnen deze constructies steeds complexer en onoverzichtelijker worden.
Met de nieuwe mogelijkheden kunnen we deze bestaande code relatief eenvoudig refactoren naar beter leesbare en dus beter onderhoudbare code.

Maar natuurlijk geldt zoals altijd: bedenk of deze complexe constructies gezien kunnen worden als code smell voor het overtreden van belangrijke SOLID principes, zoals het Open/Closed of Single Responsibility principe.
Overweeg in die gevallen vooral ook de toepassing van nette OO oplossingen, zoals het inzetten van encapsulation en de vele design patterns die beschikbaar zijn.

berglerC# 9.0 nieuwe features – Pattern Matching (2-4)
Lees meer

C# 9.0 nieuwe features – Init Only Setters (1-4)

C# 9.0 nieuwe features – Init Only Setters (1-4)

Init Only Setters

Met de komst van .NET 5 en C# 9.0 zijn er heel veel waardevolle toevoegingen gedaan aan de programmeertaal. In deze Blog serie zullen we inzoomen op een aantal belangrijke nieuwe features en we trappen af met “Init Only Setters”.

Om C# 9.0 te kunnen gebruiken dien je eerst de .NET 5 runtime of SDK te installeren. Ga hiervoor naar https://dotnet.microsoft.com/download. Na installatie zal C# 9.0 de standaard C# versie zijn bij elk nieuw project gebaseerd op .NET 5.

Waarom?

De Init Only Setters zijn aan C# toegevoegd om de ontwikkelaars een betere ervaring te geven met het maken en gebruiken van immutable classes of structs, door een extra moment te introduceren waarop data gemodificeerd mag worden.

Voorheen werd immutability verkregen door members readonly te maken of door properties niet te voorzien van een public setter. Het probleem wat hiermee ontstond, was dat je de data van het object alleen kon initialiseren via constructor parameters. Ook middels de in C# 3.0 geïntroduceerde object initializers, was het niet mogelijk om de data voor het object bij initialisatie in te stellen:

blank

Hoe?

In C# 9.0 is het nu wel mogelijk om immutable properties voor een object te initialiseren middels de object initializer. Die doe je door de setter van de property te vervangen door het nieuwe init keyword:

blank

Hiermee wordt dus voorkomen dat je expliciet constructor parameters voor alle properties moet aanmaken. Het geeft de ontwikkelaar dus veel vrijheid in het initialiseren van objecten.

Verder?

Het kunnen instellen van immutable properties middels de object initializer is verreweg het grootste voordeel wat de Init Only Setters feature biedt. De nieuwe feature kan echter breder ingezet worden, onder andere op de volgende manieren:

  • Setters van properties kunnen nu in de instance constructor van de afgeleide class ook benaderd worden:
    blank
  • Init Only Setters kunnen ook benaderd worden vanuit de body van een andere Init Only Setter:
    blank

Auteur: Patrick Vroegh © 2021 Bergler Competence Center

berglerC# 9.0 nieuwe features – Init Only Setters (1-4)
Lees meer

Bergler Technology Radar 2021

Bergler Technology Radar 2021

Ondanks dat de wereld door de pandemie sterk is veranderd en er veel tot stilstand is gekomen, gaan de veranderingen op het gebied van softwareontwikkeling onverminderd snel. Hierdoor blijft het als organisatie zaak om bij te blijven met de recente ontwikkelen. Belangrijk struikelblok is het aanbrengen van focus op de juiste topics. Wij proberen hier als ICT-dienstverlener organisaties mee te helpen, door gebruik te maken van onze kennis opgedaan bij veel verschillende opdrachtgevers. Hiervoor gebruiken wij de technology radar zoals is bedacht door trendwatchers van ThoughtWorks. Dit geeft een duidelijk overzicht van de trends welke aansluiten op onze visie binnen Bergler voor 2021.

Legenda

De technology radar is opgedeeld in 4 verschillende kwadranten. Dit zijn:

  • Techniques:
    Methodes en technieken welke van belang zijn voor verbeteringen gedurende een softwareontwikkelingstraject;
  • Platforms:
    Voor het bouwen en/of hosten van software projecten;
  • Tools:
    Voornamelijk gereedschap om het ontwikkelproces te verbeteren. Denk dan aan het inzichtelijker maken van code of processen binnen de code;
  • Languages-And-Frameworks:
    Welke ontwikkeltaal gebruik je en eventueel welk raamwerk daar bovenop?

Elk kwadrant is opgedeeld in 4 ringen die ons advies geven m.b.t. de research en development fase waarin een topic zich zou moeten bevinden. Voor ons als Bergler zijn alle topics die op onze technologie radar staan het waard om eens nader te bekijken en ze goed in de gaten te houden. De plek in de ringen zijn een algemene indicatie en dit kan per organisatie nog verschillen, afhankelijk van de businesscase. Het algemene idee achter de ringen is het volgende:

  • HOLD: Dit zijn topics met potentie welke wij goed in de gaten houden, maar die nog niet productierijp zijn, of schaduwkanten hebben die goed afgewogen moeten worden.
  • INVESTIGATE: Dit zijn topics die organisaties in ieder geval zouden moeten onderzoeken. Het zijn waardevolle tools, die productierijp zijn maar mogelijk niet voor elke organisatie dezelfde waarde toevoegen. Een goede impact analyse is aan te raden. (*)
  • TRY OUT: Dit zijn topics waarvan we adviseren om naast onderzoek ze ook actief op te nemen in proof of concepts en te beoordelen of en op welke wijze ze bij kunnen dragen aan de organisatie. (*)
  • ADOPT: Dit zijn topics waar de inzet direct wordt aanbevolen.

(*) Bepaalde topics hebben wij bewust niet in de “ADOPT” ring geplaats maar in één van de onderliggende ringen, ondanks dat het een volwassen topic betreft.  Dit kan zijn omdat zijn dat de impact van het implementeren veel impact kan hebben op b.v. de organisatiestructuur en/of werkwijze. Het is dan natuurlijk als organisatie van belang dit goed het overwegen voor men tot implementatie over gaat.

Verdieping

blankVoor alle topics welke wij in de Techradar hebben opgenomen hebben wij een verklarende tekst opgenomen. In veel gevallen zijn dit ook links naar eerder door Bergler georganiseerde sessies en of blogpost. Kijk hier voor een overzicht van de nog aankomende sessies.

We willen hier nog een aantal topics uit de technology radar uitlichten:

Threat Modeling

Wij zien Threat Modeling als een belangrijk onderdeel van een software ontwikkelingslifecycle. Door de gang naar de cloud wordt de attack surface vergroot. Hierdoor wordt het opnemen van security gerelateerde technieken in het ontwikkelproces van steeds groter belang. Threat Modeling is geen nieuwe maar wel een krachtige techniek om al vroeg in je ontwikkeltraject kwetsbaarheden te onderkennen. Wil je hier meer over weten schrijf je dan in voor ons webinar: Threat Modeling.

.NET 5

Met de komst van .NET 5 nadert het afscheid van het fullstack .NET framework. Dit heeft veel impact voor organisaties, het is niet aan te raden door te blijven ontwikkelen op de verouderde frameworks. Dit dwingt organisaties om na te denken over migratie strategieën. Wil je meer hierover weten schrijf je dan in voor ons webinar: Migratiepaden naar .NET 5.

C# 9

Het recent geïntroduceerde C# 9 geeft toegang tot nieuwe language features welke het ontwikkelen van code in C# kan vereenvoudigen.  Met Record Types worden immutable reference types op een eenvoudige manier geïntroduceerd.  Wil je meer hierover weten schrijf je dan in voor ons webinar: Value objects als records in C# 9.

Living Documentation

blankWij houden de ontwikkelingen op software development gebied nauw in de gaten. Wij als Bergler zullen onze Technology Radar dan ook bijwerken indien nodig. Blijf deze dus in te gaten houden of bezoek onze gratis webinars ter inspiratie. Mocht je meer willen weten van bepaalde topics dan kun je altijd contact met ons opnemen.

berglerBergler Technology Radar 2021
Lees meer

Jaarprogramma 2021

Jaarprogramma 2021

Jaarprogramma 2021

We kijken terug op een bewogen 2020. Toen we het competence center programma voor afgelopen jaar samenstelden gingen we uit van gezellige sessies op kantoor en in Houten. Hoe anders is de praktijk gelopen. Gelukkig hebben we afgelopen jaar gezien dat we ook online hele toffe sessies konden organiseren. De kennis sessies in Houten werden online sessies via YouTube, en met veel succes want aan het einde van het jaar hadden we maar liefst 450 aanmeldingen voor onze sessies over Docker en Kubernetes. Dat had in de ruimte in Houten nooit gepast. Ook de interne opleidingen kregen een ander karakter waarbij we op het ene scherm de Team sessie actief hadden om op het andere scherm de opdrachten uit te voeren. Iets minder persoonlijk, maar zeker werkzaam.

Zoals elk jaar hebben we samen met het team van Lead developers gekeken naar de thema’s die we dit komende jaar willen behandelen. Daarnaast is er nieuws op het vlak van ons opleidingsprogramma: komend jaar faciliteren we voor alle medewerkers een Pluralsight abonnement waar we onze doelen uit het opleidingsprogramma in opnemen. Je kunt dan denken aan zaken als SOLID development, automatisch testen, maar ook het opkrikken van algemene C# kennis. We verwachten dat we hiermee een hele mooie toevoeging doen aan het ondersteunen van onze software developers. Meer informatie volgt in de loop van het eerste kwartaal. Dan nu de thema’s voor het Competence Center programma van 2021:

Migratiepaden naar .NET 5

blankMet de komst van .NET 5 beweegt Microsoft voor het eerst in de geschiedenis definitief weg van het fullstack .NET framework. De nieuwe versie is gebaseerd op .NET Core. Wat betekent dit voor bestaande producten en welke strategieën zijn er om te migreren? Op deze vragen gaan we samen in.

Azure DevOps

blankWe hebben de afgelopen jaren al best wat aandacht besteed aan Azure DevOps. Tegelijk gaan de ontwikkelingen van dit platform erg hard, en hebben we gemerkt dat er bij collega’s behoefte is om eens stil te staan bij zaken waar je in het dagelijks werk misschien niet altijd tegenaan loopt. Enerzijds nog eens wat dieper in Git duiken, maar vooral ook kijken naar de CI/CD pipelines en planningen.

Een introductie in gRPC

blankEen van de technologieën die is geïntegreerd in .NET Core is gRPC. Omdat dit protocol een prima alternatief is voor de WCF services die niet meer beschikbaar zijn in .NET Core, is er alle reden om deze technologie te bestuderen.

Een introductie in Blazor

blankMet de komst van Blazor introduceert Microsoft haar visie op single page front-end development op basis van C#. Hierbij wordt gebruik gemaakt van web assembly, een standaard van W3C die door alle grote browsers ondersteund wordt. We zullen zeker stilstaan bij de roerige wereld van de front-end development en welke strategie hier het beste bij past. Duidelijk is in ieder geval dat er een risico is dat in de front-end weer monolitische applicaties ontstaan die in de toekomst lastig te onderhouden zijn. Hoe verhoudt Blazor zich in dit speelveld en hoe kun je ook in de front-end met deze technologie kleine micro clients maken die samen toch als één applicatie voelen.

blank

Bergler hackaton

Juist omdat we elkaar het laatste jaar zo weinig hebben gezien, is het idee ontstaan om komend jaar eens iets nieuws te proberen. Op zaterdag 29 mei organiseren we een hackaton waar onze collega’s op een leuke manier nieuwe technieken kunnen uitproberen, gezellig samen kunnen komen en voor de eeuwige developer roem mogen strijden. Ik hoop dat dit een groot succes mag worden en dat we nog vele soortgelijke events mogen organiseren.
blank

… En nog veel meer

Los van de bovenstaande hoofdthema’s worden er nog vele kleinere sessies georganiseerd. Voor het volledig programma verwijs ik graag naar onze flyer.

Met vriendelijke groet,
Menno Jongerius

berglerJaarprogramma 2021
Lees meer

Authenticatie in ASP .NET Core 3.1

Authenticatie in ASP .NET Core 3.1

Authenticatie in ASP .NET Core 3.1

Authenticatie en autorisatie worden vaak in één adem genoemd en zijn in zekere zin ook onlosmakelijk aan elkaar verbonden. Toch hebben ze ieder hun specifieke verantwoordelijkheid. Met behulp van authenticatie kunnen gebruikers van een webapplicatie zich identificeren om toegang te krijgen tot de applicatie. Met autorisatie kunnen ze toegang krijgen tot specifieke functies en functionaliteit van een webapplicatie.

ASP.NET Core Identity is een zogenaamd membership system dat gebruikt wordt bij het bouwen van ASP.NET Core-webapplicaties, inclusief lidmaatschap, inloggen en gebruikersgegevens. ASP.NET Core Identity maakt het mogelijk om inlogfuncties toe te voegen aan een webapplicatie en maakt het eenvoudig om gegevens over de ingelogde gebruiker toe te passen.

ASP.NET Core Identity maakt authenticatie voor één enkele applicatie mogelijk. Het heeft zoals aangegeven redelijk wat features “out-of-the-box”. Wanneer je authenticatie op een meer gecentraliseerde en geïsoleerde manier wilt gebruiken voor meerdere client applicaties is het beter te kijken naar een token service met OAuth 2.0 and OpenID Connect implementatie zoals IdentityServer.

In dit artikel wordt één van de manieren beschreven waarop binnen ASP.NET Core 3.1 authenticatie kan worden geregeld met behulp van Identity Core. Het uitgebreidere IdentityServer behoort niet tot de scope van dit artikel.

De volgende items zullen aan de orde komen:

  • Opzetten ASP.NET Core Identity framework (EF Core 3.1 & migrations)
  • Registratie van nieuwe gebruikers
  • In-/uitloggen van gebruikers
  • Account Lockout mechanisme
  • Custom validatie naast de al in Identity aanwezige default validatie

Opzetten ASP.NET Core Identity framework

Er bestaan in Visual Studio diverse templates die kunnen worden gebruikt bij het opzetten van een Identity Core framework. In alle gevallen is de basis een context die is afgeleid van IdentityDbContext. Dit is de base class voor de EF Core database context die gebruikt wordt voor Identity en waaraan het User objecttype wordt meegegeven:

blank

In de OnModelCreating methode kan een verdere configuratie van de objecten plaatsvinden zoals het verplicht maken van velden of het initiëren van de tabellen met bepaalde default data.

Daarnaast is in bovenstaande code snippet een DbSet aangemaakt die gebruikt gaat worden als IdentityUser object (en die is afgeleid van de IdentityUser base class).

Het registreren van de Identity DB context service en de setup voor het gebruik van (in dit geval) SQL Server gebeurt in de ConfigureServices methode van startup.cs:

blank

Na het uitvoeren van de diverse EF Core migration commando’s is er in SQL Server een Identity database aangemaakt met daarin een aantal standaard Identity tabellen (welke allemaal de prefix ‘AspNet’ hebben):

blank

In de volgende paragrafen zullen de betekenis en functie van diverse velden uit m.n. de AspNetUsers tabel verder aan de orde komen. Voor dit artikel zijn de volgende tabellen en hun onderlinge relatie van belang:

blank

Om de Identity Core functionaliteit beschikbaar te maken in de applicatie zijn tot slot twee zaken nodig in de startup.cs:

  1. Het registreren van de services voor het ASP.NET Core Identity framework (in de ConfigureServices methode):
    blank
  1. Het toevoegen van de authenticatie middleware (in de Configure methode):
    blank

Registratie van nieuwe gebruikers

Om nieuwe Identity Users te registreren wordt gebruik gemaakt van de UserManager class. Deze class bevindt zich in de namespace Microsoft.AspNetCore.Identity en wordt d.m.v. dependecy injection in een controller geïnjecteerd:

blank

Om een nieuwe gebruiker te registreren is het noodzakelijk naast een gebruikersnaam en/of emailadres ook een wachtwoord op te geven. Met behulp van deze gegevens kan een gebruiker door de applicatie geauthentiseerd worden.

Er kan m.b.t. authenticatie gekozen worden voor de combinatie gebruikersnaam/wachtwoord of emailadres/wachtwoord. Wanneer voor de laatste optie wordt gekozen is het aan te raden tijdens het registreren van de services voor het ASP.NET Core Identity framework de optie mee te geven dat gevalideerd moet worden dat het emailadres van de nieuw toe te voegen Identity User uniek is (User.RequireUniqueEmail = true).

Voor de eerste optie geldt by design dat het Identity framework valideert dat de gebruikersnaam van de nieuw toe te voegen Identity User uniek is.

Registratie gebeurt vervolgens in een POST action in de controller:

blank

De return value van deze (async) functie is van het type IdentityResult en bevat een boolean flag Succeeded die aangeeft of de actie geslaagd is of niet. Indien de actie niet succesvol was bevat de property Errors de fout(en) die is/zijn opgetreden bij de CreateAsync actie.

Het wachtwoord wordt (indien de operatie succesvol was) volgens een hashing algoritme encrypted opgeslagen in de database. Daarnaast worden enkele velden automatisch gevuld zoals het NormalizedUserName en het NormalizedEmail veld.

In-/uitloggen van gebruikers

Zoals aangegeven worden gebruikers geauthentiseerd op basis van een gebruikersnaam/wachtwoord of emailadres/wachtwoord combinatie. Het ASP.NET Core Identity framework biedt hiervoor twee mogelijkheden die ieder een verschillend doel dienen:

  1. CheckPasswordAsync

Deze methode hasht het opgegeven wachtwoord en vergelijkt het met de bestaande wachtwoordhash (zoals dat bijvoorbeeld is opgeslagen in de database)

  1. PasswordSignInAsync

Deze methode doet naast het controleren van het wachtwoord veel meer:

  • Controleert of inloggen is toegestaan. Als de gebruiker bijvoorbeeld een bevestigde e-mail moet hebben voordat hij zich mag aanmelden, retourneert de methode Failed
  • Roept UserManager.CheckPasswordAsync op om te controleren of het wachtwoord correct is. Wanneer een mislukte inlogpoging (wachtwoord is niet correct en de Lockout optie is enabled) het geconfigureerde maximum aantal mislukte aanmeldingspogingen overschrijdt wordt het account van de gebruiker geblokkeerd
  • Als de optie two-factor authentication is ingeschakeld voor de gebruiker, stelt deze methode de cookie in en retourneert TwoFactorRequired
  • Maakt een ClaimsPrincipal aan en persisteert dit via een cookie

 

Wanneer bevestigde e-mails en lockout geen vereiste zijn dan volstaat het om de CheckPasswordAsync methode uit de UserManager class te gebruiken. De SignInManager class is gekoppeld aan de cookie-authenticatie.

De volgende code snippet toont een manier om door middel van emailadres/wachtwoord combinatie authenticatie van een gebruiker te doen:

blank

Analoog aan bovenstaande code snippet kan een gebruiker worden geauthentiseerd via zijn/haar gebruikersnaam.

In de volgende paragraaf wordt uitgebreider ingegaan op het Lockout mechanisme waarmee restricties kunnen worden gesteld aan het aantal pogingen dat een gebruiker mag doen om zichzelf bij een applicatie te authentiseren.

Account Lockout mechanisme

Het ASP.NET Core Identity framework biedt standaard een aantal belangrijke beveiligingsfuncties die het authenticatieproces van extra checks te voorzien. Denk hierbij aan:

  • Two-Factor Authentication (met behulp van SMS of email)
  • Account Lockout
  • Account Confirmation

Account Lockout is een belangrijke functie van het ASP.NET Core Identity framework. Het blokkeert het account van de gebruiker als deze een bepaald aantal keren een verkeerd wachtwoord invoert. Dit kan worden gespecificeerd door het maximale aantal mislukte pogingen (default 5x) en de lockout-tijd (default 5 minuten) te configureren in startup.cs:

blank

De volgende code snippet toont het gebruik van het Lockout mechanisme: een mogelijkheid om het aantal inlogpogingen te beperken tot een opgegeven maximum. Zoals in de vorige paragraaf aangegeven is het hiervoor noodzakelijk gebruik te maken van de SignInManager.PasswordSignInAsync methode. Door de parameter lockoutOnFailure te activeren (true), wordt de lockout-functionaliteit ingeschakeld.

blank

Custom validatie

Naast de standaard al aanwezige validatie in het ASP.NET Core Identity framework is het mogelijk eigen validatie toe te voegen zoals bijvoorbeeld het controleren op emaildomein of het uitsluiten van de mogelijkheid dat gebruikersnaam en wachtwoord identiek zijn. De volgende code snippets tonen enkele mogelijke custom validatie’s.

blank

Het opnemen van de (extra) custom validatie’s gebeurt in startup.cs:

blank

Auteur: Pieter Baart © 2020 Bergler Competence Center

berglerAuthenticatie in ASP .NET Core 3.1
Lees meer

Agile werken en denken in relatie tot ISO 27001 (of welke geformaliseerde certificering dan ook)

Agile werken en denken in relatie tot ISO 27001 (of welke geformaliseerde certificering dan ook)

Als Scrum Master ben ik onlangs betrokken geweest bij het verkrijgen van een ISO 27001 certificering voor mijn eindklant.
Het hebben van een ISO 27001 certificering als organisatie betekent dat het voldoet aan de privacy- en securityrichtlijnen die zijn gedocumenteerd door ISO: https://www.iso.org/standard/54534.html.

De certificering omvat richtlijnen voor de volgende gebieden:

  • Kantoor toegangsbeveiliging
  • Werkplek beveiliging
  • Infrastructuur (netwerk & telefonie) beveiliging
  • Applicatie en data beveiliging

De richtlijnen concentreren zich vooral op de werkprocessen en minder op (technische) oplossingen. Het verwijst echter wel naar andere standaarden. Bijvoorbeeld op het gebied van applicatie & data beveiliging, verwijst het naar OWASP richtlijnen.

De perceptie van iedere vorm van certificering is dat het bureaucratie introduceert die wordt vastgelegd in uitgebreide documentatie die (bijna) niemand leest. Ik hoop met dit artikel te beschrijven dat deze perceptie enige nuance verdient.

blank

De nuance wil ik aanbrengen door middel van het doorlopen van het ‘Agile Manifesto’ (https://agilemanifesto.org/iso/nl/manifesto.html). Hoewel het Manifesto al twee decennia geleden is opgesteld, is tegenwoordig het voor bedrijven nog steeds het handvat voor softwareontwikkeling. Het Manifesto heeft 4 kernwaarden:

  • Mensen en hun onderlinge interactie boven processen en hulpmiddelen
  • Werkende software boven allesomvattende documentatie
  • Samenwerking met de klant boven contractonderhandelingen
  • Inspelen op verandering boven het volgen van een plan

Discussie over deze kernwaarden heb ik nogal eens waarbij het idee leeft dat zodra ‘agile’ wordt gewerkt, er anarchie is over de software implementatie en bewaking. Ook dit verdient nuance.

Mensen en hun onderlinge interactie

Het voorbereiden op een ISO-audit vereist een nauwe samenwerking tussen afdelingen en medewerkers om de processen in kaart te brengen. Deze ‘agile’ waarde komt juist tot zijn kracht op het moment dat processen worden beschreven die ondersteunend zijn aan de medewerkers. Een Scrum ritueel als bijvoorbeeld Sprint Review kan hierbij faciliteren. Doordat mensen samenwerken komen tekortkomingen en kansen boven drijven. ISO-richtlijnen geeft hierbij handvatten voor aandachtsgebieden. Kortom, als we deze kernwaarde beschouwen, versterken ISO en Agile elkaar.

Werkende software

Om tot werkende software te komen zijn nu eenmaal binnen een team afspraken noodzakelijk die beschrijven hoe code de ‘softwarefabriek’ doorloopt. Hierbij is cruciaal dat vooraf acceptatiecriteria zijn opgesteld en dat deze bij oplevering worden getoetst. ISO stelt geen voorwaarden welke stappen de ‘softwarefabriek’ moet bevatten. Echter, het stelt voorwaarden dat vooraf wordt nagedacht over de gevolgen voor de gebruiker of organisatie op het gebied van gegevens beveiliging. Het team heeft hiervoor velden in Azure DevOps geïmplementeerd om de gevolgen op beveiliging en privacy te documenteren (‘Security and privacy by design’). Het vooraf opstellen van de verwachte gevolgen voorkomt bevindingen later in de ‘softwarefabriek’.

Veel teams hebben een platform om hun software te documenteren. Vaak bevat dit platform ook een beschrijving van hun ‘softwarefabriek’. Het ontwikkelteam heeft ervoor gekozen de documentatie te borgen in hun ‘eigen’ omgeving; Azure DevOps. Deze heeft een Wiki. Op deze manier is de impact voor het team minimaal omdat het geen andere omgeving eigen hoeft te maken. Voor de softwareontwikkelaars is code eigenlijk de documentatie.

De Wiki die in het ontwikkelteam gebruikt bevat niet meer documentatie dan de samenhang van onderdelen in het landschap. UML-modellen worden niet vereist en ook niet gebruikt omdat deze te weinig actueel blijven. De Wiki helpt nieuwe teamleden tijdens het inwerkproces.

Daarnaast is de integratie met het volgen van de softwareontwikkeling naadloos. In de documentatie zijn gegevens als bijvoorbeeld openstaande bugs online beschikbaar bij de documentatie.

blank

Samenwerking met de klant

Vooral op het gebied van vooraf nadenken over gevolgen op privacy en beveiliging komt het team nader tot de klant. Hierbij wordt het discussiëren over een wens met dubieuze gevolgen niet uit de weg gegaan. Het heeft de organisatie geholpen om voor grotere user stories (‘Epics’) een “Data Protection Impact Assessment” op te stellen. Net zoals bij de vorige kernwaarde, geeft dit eerder in het ontwikkelproces heldere verwachtingen over de gevolgen en daarmee de maatregelen die erbij horen.

Inspelen op verandering

ISO stelt geen eisen over het te volgen ontwikkelproces. Als Scrum Master faciliteer ik de werkvormen en rituelen van het Scrum Framework. Het is een kwestie van documenteren hoe deze werkvormen in dagelijkse operatie worden uitgevoerd. Uitkomst van een Retrospective worden opgenomen in de Product Backlog. Bevindingen en opmerkingen tijdens een demo worden als ‘bevinding’ opgenomen in de Product Backlog.

Zolang de werkvormen en de workflow van de organisatie zijn gedocumenteerd, is deze kernwaarde eenvoudig te beschrijven conform ISO-richtlijnen. Het is eigenlijk niet meer dan ‘prove what you have written down’. Azure DevOps biedt hiervoor uitstekende tracking gereedschappen waarbij vanaf user story tot en met productie oplevering alles is te herleiden.

Conclusie

Eerlijk is eerlijk, vooraf was ik sceptisch over het te volgen traject. Echter, juist de kernwaarden van het Agile Manifesto hebben de organisatie geholpen om pragmatisch en gestructureerd zich voor te bereiden op de ISO-certificering. Als Scrum Master had ik het belang dat de gevolgen voor het ontwikkelteam werden beperkt. Dat is gelukt; geplande opleveringen en kwaliteit hebben geen nadelige gevolgen ondervonden.

blankIk kan melden dat de organisatie met vlag en wimpel het ISO 27001 certificaat heeft gehaald. Wil je meer weten hoe ik dit het met de organisatie en het team heb aangepakt? Ik ben bereikbaar via akraak@bergler.nl, 076 – 572 02 00 of info@bergler.nl.

Auteur: Arjen Kraak © 2020 Bergler Competence Center

berglerAgile werken en denken in relatie tot ISO 27001 (of welke geformaliseerde certificering dan ook)
Lees meer

Python, een korte introductie (voor C# ontwikkelaars)

Python, een korte introductie (voor C# ontwikkelaars)

Python is een ontwikkeltaal die al enige tijd sterk in opkomst is. Als ‘T-shaped’ software ontwikkelaar kunnen we hier niet langer om heen. Dit is voor ons ook de aanleiding geweest om eens een blik te werpen op deze taal. In dit artikel willen we een globale introductie geven van Python de ontwikkeltaal en daarnaast de kenmerkende verschillen met C# aanstippen.

Hoe is het ontstaan
“Python is een programmeertaal die begin jaren 90 ontworpen en ontwikkeld werd door Guido van Rossum, destijds verbonden aan het Centrum voor Wiskunde en Informatica (daarvoor Mathematisch Centrum) in Amsterdam. De taal is mede gebaseerd op inzichten van professor Lambert Meertens, die een taal genaamd ABC had ontworpen, bedoeld als alternatief voor BASIC, maar dan met geavanceerde datastructuren. Inmiddels wordt de taal doorontwikkeld door een enthousiaste groep, tot juli 2018 geleid door Van Rossum. Deze groep wordt ondersteund door vrijwilligers op het internet. De ontwikkeling van Python wordt geleid door de Python Software Foundation. Python is vrije software.
Python heeft zijn naam te danken aan het favoriete televisieprogramma van Guido van Rossum, Monty Python’s Flying Circus.”
Bron: https://nl.wikipedia.org/wiki/Python_(programmeertaal)

Toepassingsgebieden
Python is geschikt voor een breed scala aan, zo niet alle, toepassingsgebieden. De voornaamste toepassingsgebieden waar Python momenteel wordt gebruikt zijn:

  • (BI) Data science
  • (ML) Machine Learning
  • (AI) Artificial Intelligence
  • (IOT) Internet Of Things

Andere toepassingsgebieden zijn o.a.:

  • Web applicaties
  • Web (REST) API’s
  • Desktop applicaties
  • OS scripting

Kenmerken
In onderstaande tabel worden enkele kenmerken van de Python programmeertaal opgesomd met daarnaast de C# programmeertaal als tegenhanger:
blank

Dynamically typed versus statically typed

In een ‘dynamically typed’ programmeertaal zoals Python, is het niet noodzakelijk om variabelen met een bepaald type van te voren te declareren. Een variabele kan zelfs tijdens de uitvoering van het programma van type wisselen. In een ‘statically typed’ programmeertaal zoals bijvoorbeeld C#, dienen de variabelen van te voren, als zijnde van een bepaald type, te worden gedeclareerd.
De onderstaande code is correct in Python, maar zal compiler fouten opleveren in C#:

Python:
blank

Deze code zal zonder problemen worden uitgevoerd en print de tekst “Hello world” in de console.
blank
Figuur 1- Dynamically typed voorbeeld

C#:
blank

Deze code zal niet compileren en zal dus niet worden uitgevoerd.

blank
Figuur 2- Strongly typed voorbeeld

Duck typed vs Strongly typed

De term ‘Duck typing’ is voortgekomen uit de zin “If it looks like a duck and quacks like a duck, it is a duck” en wordt voornamelijk toegepast in dynamische programmeertalen. Bij duck typing gaat men ervan uit dat je geen type nodig hebt om een bestaande methode op een object uit te voeren, zolang de methode zelf maar aanwezig is. De volgende python code is een voorbeeld van Duck typing en compileert zonder problemen:

blank
Figuur 3- Duck typing in dynamische taal

Het probleem komt pas boven water tijdens de uitvoering van het programma (run time):

blank
Figuur 4- Runtime error

Omdat C# een strongly typed programmeer taal is zal zulke code direct leiden tot een compiler error, omdat de compiler niet het juiste type van de objecten kan bepalen:

blank
Figuur 5- Compile error

Indentation based vs syntax based

Python is ‘Indentation based’ de code van een Python programma is gestructureerd d.m.v. ‘indentation’ (inspringen), terwijl de code van een C# programma gebaseerd is op een vastgelegde syntax. Om binnen Python aan te geven dat een stukje code bij elkaar hoort en gezien dient te worden als 1 code blok gebruik je ‘indentation’. De scheiding van de verschillende code blokken wordt aangegeven door 1 of meerdere lege regels.

blank
Figuur 6- Frame class in Python gebaseerd op ‘indentation’

In een op syntax gebaseerde programmeertaal, zoals C# worden de code blokken gedefinieerd doordat de verschillende code regels omsloten zijn door een bepaald symbool, in C# zijn dit de accolades {}.

blank
Figuur 7- Frame class in C# gebaseerd op syntax

Object georiënteerd

Zowel Python als C# zijn programmeer talen waarin je object georiënteerd kunt programmeren. Een van de kenmerken van object georiënteerd programmeren is overerving. Dit kan in Python als wel in C# gerealiseerd worden. De volgende code snippets geven een voorbeeld van een Persoon class en een Student class, waarbij de Student class afgeleid is (overerft) van de Persoon class.

Overerving in Python:
blank
Figuur 8- Voorbeeld overerving in Python

Overerving in C#:
blank
Figuur 9- Voorbeeld overerving in C#

Programmeer-oefening Python

Voor onze interne competence center avond (pizza-avond) hadden we een oefening voorbereid, waarmee onze collega’s aan de slag konden om zo wat eerste ervaringen op te doen met programmeren in Python. Deze oefening is gebaseerd op de wel bekende ‘Bowling kata’.
Mocht je interesse zijn gewekt om eens met Python aan de slag te gaan, dan kan je deze oefening hier vinden:
Bowling Kata programmeer oefening.

In het readme.md bestand vind je een beschrijving van de oefening en hoe je hiermee aan de slag kunt gaan.
Veel plezier op je Python ontdekkingsreis!

Auteur: Marcel Slegt © 2020 Bergler Competence Center

berglerPython, een korte introductie (voor C# ontwikkelaars)
Lees meer

Zeven tekenen van rottende software

Zeven tekenen van rottende software

Hopelijk begin je een software ontwikkeling met een redelijk tot goed idee hoe de toekomstige software er uit moet zien. Een helder beeld hebben van de toekomstige software is belangrijk voor jezelf en voor je team. Als je geluk hebt, overleeft dit beeld het tot de eerste release. Maar na verloop van tijd gebeurt er iets, de software begint langzaam maar zeker te ruiken als een stuk bedorven vlees.

Hoewel geen enkele ontwikkelaar dit wil, is het een realiteit die ik maar bij al te veel ontwikkelaars tegenkom. In de loop van de tijd is onder druk van deadlines, wijzigende functionaliteit, wijzigende teamsamenstelling de software langzaam maar zeker steeds ondoorzichtiger geworden. In dit document ga ik in op zeven tekenen van software rot en wat je kunt doen om dit zoveel mogelijk te voorkomen.

Rigiditeit
Rigide software is software die moeilijk aan te passen is. Een op het eerste gezicht simpele aanpassing stuurt resulteert in een cascade van gevolgschade in diverse modules. Hoe meer plekken geraakt worden door aanpassingen, hoe meer rigide het systeem is. Veel ontwikkelaars herkennen hoe een simpele aanpassing een waterval van ellende over ze heen stort waardoor ze steeds meer code moeten aanpassen en de wijziging veel langer duurt dan oorspronkelijk was ingeschat. Als ze dan gevraagd wordt waarom hun inschatting zoveel te laag was, volgt het traditionele antwoord “het was een stuk complexer dan ik had verwacht.”

Breekbaarheid
De breekbaarheid van een systeem wordt bepaald door de kans dat een wijziging op één plek op vele andere plekken onverwachte fouten introduceert. Soms kan het voorkomen dat er fouten optreden op plekken die niet logischerwijs gerelateerd zijn aan de aangebrachte wijziging.

Immobiliteit
Een ontwerp is immobiel wanneer het componenten bevat die voor andere systemen nuttig zouden zijn, maar niet geïsoleerd kunnen worden omdat het risico en de kosten om ze uit het originele systeem te halen gewoonweg te groot zijn.

Viscositeit
Als er een wijziging in software moet worden aangebracht kan dit meestal op meerdere manieren. Sommige manieren zijn in lijn met het ontwerp en de architectuur van de software en andere niet (ook wel hacks genoemd). Een systeem heeft een hoge viscositeit wanneer een aanpassing in lijn met de architectuur meer tijd kost dan een hack. Naast de viscositeit van de software is er ook nog de viscositeit van de ontwikkelomgeving in zijn geheel. Wanneer het uitvoeren van geautomatiseerde tests heel veel tijd kost, is het waarschijnlijk dat de ontwikkelaar een wijziging doorvoert zonder de juiste testen op te zetten.

Nodeloze herhaling
Of ook wel het knippen en plakken van code genoemd. Meestal wordt dit veroorzaakt doordat het systeem niet de juiste abstracties implementeert en niet conform design patterns als SOLID is opgezet. Vaak is het een teken dat er te weinig tijd (of ervaring) binnen een team is om na te denken over architectuur. Wat overblijft, is veelal procedurele code die weliswaar functioneert, maar lastig te onderhouden is.

Duidelijkheid
De duidelijkheid van een module bepaald in hoeverre het eenvoudig is voor een ontwikkelaar om een module te begrijpen. Code die met de tijd doorontwikkeld is, heeft de neiging om steeds minder duidelijk te zijn.

Nodeloze complexiteit
Dit is misschien wel een van de lastigste punten om aan te pakken. Gepassioneerde ontwikkelaars zullen in hun inzet om de overige zes tekenen van software rot te voorkomen, mogelijk in de valkuil van deze zevende stappen. Een goed software ontwerp is lichtgewicht, flexibel, eenvoudig om te begrijpen en bovenal eenvoudig om aan te passen.

blankOmgaan met rottende software
Helaas is er geen “silver bullet” als het gaat om software rot. Ervaren ontwikkelaars zullen misschien minder snel in valkuilen stappen dan minder ervaren ontwikkelaars, maar uiteindelijk maken we allemaal fouten.

Er zijn wel een aantal zaken die helpen om software rot te voorkomen:

  • Zorg dat de software voldoende afgedekt is door automatische testen
  • Zorg bij iedere wijziging en nieuwe feature voor voldoende tijd om te refactoren
  • Peer review elkaars code
  • Pair program wanneer je een ingewikkeld stuk moet opzetten
  • Zorg voor heldere coding guidelines voor het team
  • Maak architectuurbeslissingen altijd met meerdere ontwikkelaars samen

“Last-but-not-least” zoals een collega van mij vaak mooi weet te zeggen: “perfect is the enemy of good”. Probeer niet de perfecte architectuur te maken, die bestaat niet, en waarschijnlijk wordt je systeem al snel nodeloos complex.

Auteur: Menno Jongerius © 2020 Bergler Competence Center

berglerZeven tekenen van rottende software
Lees meer