netwinst software architectuur
DESCRIPTION
Presentatie van Benno van Dijk, over de nieuwe software architectuur van Netwinst.TRANSCRIPT
NetWinst backend workflowHet schrijven van “mooie” code.
08-04-2023NetWinst backend workflow2
AgendaHet doelApplicatie ArchitectuurWerken met componentenTesten (Unit Tests en Integration Tests)DatabasesVersiebeheer: best practicesConcreet voor NetWinstWrap upVragen/discussie
Het doel
08-04-2023NetWinst backend workflow4
Een project dat zo…
08-04-2023NetWinst backend workflow5
snel tot
stand komt…
08-04-2023NetWinst backend workflow
zo makkelijk en snel te onderhouden
is…
708-04-2023NetWinst backend workflow
zo op de toekomst gebouwd is…
808-04-2023NetWinst backend workflow
zo Weinig
Bugs bevat…
08-04-2023NetWinst backend workflow
en zo Makkelijk over te nemen is door andere programmeurs…
10
dat het bijna eng is!
11
Het creëren van een standaard
Programming Patterns Unit tests Componenten
Convention over configuration
Versiebeheer &documentatie
Standaard is leidend
Applicatie Architectuur
08-04-2023NetWinst backend workflow13
Applicatie ArchitectuurWaarom is een onderliggende architectuur noodzakelijk?Wat is er mis met ASP.NET web forms?Wat is het MVC pattern?Wat zijn de voordelen van MVC?Waarom ASP.NET MVC?Het opdelen van een applicatie in lagen Lagen en verantwoordelijkheden
08-04-2023NetWinst backend workflow14
The Alice in Wonderland Experience
08-04-2023NetWinst backend workflow15
Waarom is een onderliggende architectuur belangrijk?
Elk onderdeel heeft z’n eigen verantwoordelijkheid• Single responsibility principe
Het stimuleert toepassing van het DRY principe• DRY = Don’t repeat yourself
Gestructureerde en makkelijk uitbreidbare codeHet maakt geautomatiseerd testen van applicaties eenvoudigHet stimuleert tot het schrijven van betere codeProgrammeurs zijn makkelijk inzetbaar op andere projectenFocus op de business logicaKortere doorlooptijd van projectenMinder bugs
08-04-2023NetWinst backend workflow16
Of in één woord…
Efficiëntie
08-04-2023NetWinst backend workflow17
Wat is er mis met ASP.NET web forms?
Web forms creëert een gigantische abstractielaag die zowel HTTP als HTML probeert te maskerenHet doel van Microsoft was om web development exact hetzelfde aan te laten voelen als applicatie developmentHierdoor ontstaat gelimiteerde controle, vaak omzeilt door “lelijke” hacks
08-04-2023NetWinst backend workflow18
Stateful UI versus Stateless UI
08-04-2023NetWinst backend workflow19
ViewstateWeb Forms imiteert een stateful UI door de status van ieder element op te slaan in de viewstate. Op data intensieve pagina’s soms tot honderden kb’s die elke request en response op en neer gestuurd worden!!!
08-04-2023NetWinst backend workflow20
Web control vs. Html element
HTML<input id=“txt_test” type=“text” value=“hallo” />
ASP.NET web control<asp:TextBox id=“txt_test” runat=“server” Text=“hallo” />
08-04-2023NetWinst backend workflow21
Misplaatst idee van scheiding HTML en logica
Web Form pagina’s bestaan uit:• Code Front: de html en web controls• Code Behind: de code voor het manipuleren van de web
controls en reageren op events
Code Behind classes worden onterecht gebruikt voor:• Business Logica• Queries
Business logica zit overal verspreidOnhandelbare grote Code Behind classes
08-04-2023NetWinst backend workflow22
Gelimiteerde controle HTMLGeen of weinig controle over de gegenereerde HTMLProgrammeurs moeten HTML geschreven door de front-enders om schrijven naar Web Forms controls (dubbel werk!)Property namen en web control namen zijn anders dan hun verwante HTML variant. Je werkt dus in twee dialectenWeb controls voeren functionaliteiten uit die tegenwoordig verwacht worden van JavaScript
08-04-2023NetWinst backend workflow23
Slecht te testenEen architectuur waarbij alle elementen sterk afhankelijk van elkaar zijn, is een nachtmerrie voor geïsoleerd testen van functionaliteit.
“Spaghetti Code”
08-04-2023NetWinst backend workflow24
Tijd voor verandering
Embrace the web!ASP.NET MVC
08-04-2023NetWinst backend workflow25
Wat is het MVC pattern?
1. Interactie gebruiker (Controller)2. Model wordt geüpdatet (Model)3. UI refreshen o.b.v. nieuwe Model
(View)
08-04-2023NetWinst backend workflow26
ASP.NET MVC in actie
/Car/Rent
CarController.cs
Detail
Add
Rent
CarReservation.csViews/Reservation/Confirmation.cshtml
08-04-2023NetWinst backend workflow27
Wat zijn de voordelen van MVC?Gescheiden verantwoordelijkheden • Separation of concerns, Single Responsibility
pattern
Eenvoudig geautomatiseerd testen van complexe geïsoleerde stukjes codeHerbruikbare codeConvention over configurationMVC leent zich perfect voor websites
08-04-2023NetWinst backend workflow28
ASP.NET MVC en het web, soulmates?
De lagen die normaal komen kijken bij web development passen goed bij de componenten van het MVC model:• HTML (View)• Business Model (Model)• Uitvoerbare Code (Controller)
Werkt hand in hand met JavaScript en AJAXVolledige controle over de HTMLUnit testen, rechtstreeks in Visual Studio
08-04-2023NetWinst backend workflow29
ASP.NET MVC routing engineASP.NET MVC heeft een krachtige routing engine, waardoor URL's altijd goed leesbaar en zoekmachinevriendelijk zijn.
Geen “/Prijslijsten/Detail.aspx?id=1” meer, maar
“/Prijslijsten/Detail/1”
08-04-2023NetWinst backend workflow30
Razor: de nieuwe view engine Van .aspx naar .cshtmlClean en minimalistisch
08-04-2023NetWinst backend workflow31
Het opdelen van een applicatie in lagen
08-04-2023NetWinst backend workflow3232
Web UI (ASP.NET MVC 4)
Service Layer
Business Domain
Repository Pattern
Entity Framework
Data LayerUnit Tests
08-04-2023NetWinst backend workflow33
Lagen en verantwoordelijkheden
Laag Verantwoordelijkheid
Web UI Layer Views en Controllers
Business Domain Layer Model
Service Layer Query’s en services
Data Layer Communicatie Database
Unit Test Layer Unit Tests
08-04-2023NetWinst backend workflow34
Waarom naast MVC nog de extra Service Layer?
De Service Layer zorgt ervoor dat query’s op een centrale plek staan en dus herbruikbaar zijnDe Service Layer stelt je in staat om complexe query’s te testen aan de hand van unit testsDe Service Layer is de ideale plek voor services/componenten die centraal bereikbaar moeten zijn, maar niet in het business model thuis horen (bv. CopernicaEmailService)
Werken met componenten
08-04-2023NetWinst backend workflow36
Componenten en ExtensiesComponenten Extensies
Email Service Component Opmaak van tekst
Login Component Berekeningen met datums
Formulier component Simpele interface voor het uitvoeren van generieke, complexe taken
Rollen en Rechten Component
08-04-2023NetWinst backend workflow37
Hoe bouwen we deze componenten?Net als de projectspecifieke code, zijn de componenten te verdelen over de verschillende lagen• HTML (web UI project, views)• Gebruikers interactie (web UI project, controllers)• De implementatie/logica (Service Layer)• De domein classes (Business Domain, optioneel)
08-04-2023NetWinst backend workflow38
Hoe koppelen we deze componenten aan onze projectspecifieke code?
Interfaces, de sleutel tot flexibiliteitEen interface is het contract tussen de gebruiker en een object.Het beschrijft wat er gedaan moet worden, zonder zich te bekommeren om de onderliggende implementatieDenk bijvoorbeeld aan de knoppen op een radio, de knoppen zijn in dit geval de interface De onderliggende werking boeit ons niet, zolang aan de verwachting in het contract voldaan wordt
08-04-2023NetWinst backend workflow39
08-04-2023NetWinst backend workflow40
08-04-2023NetWinst backend workflow41
Inversion of control - voorbeeld
Implementatie Email Service Component
Implementatie Copernica Email Service Component
Interface IEmailService
- SendEmail- LogEmail- GetEmailsForUser
Interface ICopernicaService
- UpdateProfile- LogCopernicaEmail- GetCopernicaEmailL
og
Applicatie
Afhankelijkheid van email service component
08-04-2023NetWinst backend workflow42
Inversion of control - voorbeeld
Implementatie Email Service Component
Implementatie Copernica Email Service Component
Applicatie Interface IEmailService
- SendEmail- LogEmail- GetEmailsForUser
08-04-2023NetWinst backend workflow43
Inversion of control
08-04-2023NetWinst backend workflow44
Inversion of control
08-04-2023NetWinst backend workflow45
Dependency InjectionOp één centrale plek de mapping regelen tussen interfaces en implementaties van die interfaces
08-04-2023NetWinst backend workflow46
Inversion of control - voorbeeld
Implementatie Email Service Component
Implementatie Copernica Email Service Component
Applicatie Interface IEmailService
- SendEmail- LogEmail- GetEmailsForUser
IEmailService -> Copernica Email Service Component ILoginService -> MultiLogin Service Component
08-04-2023NetWinst backend workflow47
Mission Accomplished – volledig losgekoppeld
Functionaliteit van een component kan gewijzigd worden zonder één regel code te veranderen in de rest van de applicatieEen compleet component kan vervangen worden zonder één regel code te veranderen in de rest van de applicatie
Testen (Unit Tests en Integration Tests)
08-04-2023NetWinst backend workflow49
Voordelen van unit testsSchrijven van code met testen in het achterhoofdTests maar één keer schrijven en oneindig uitvoerenGeen insluipende bugs meer
08-04-2023NetWinst backend workflow50
Kenmerken van een goede unit test
Focus op een geïsoleerd stuk codeIs altijd goed óf altijd fout (pass/fail)OnafhankelijkSnelDek alle functionaliteitGoed omschrijvende namen• Dog_object_should_eat_homework_object_when_hungry(
)
08-04-2023NetWinst backend workflow51
AAA (Arrange, Act, Assert)Arrange: klaarzetten testsituatieAct: uitvoeren testsituatieAssert: klopt resultaat met verwachting
08-04-2023NetWinst backend workflow52
Unit test - voorbeeld
08-04-2023NetWinst backend workflow53
Unit Test - Resultaat
08-04-2023NetWinst backend workflow54
Integration/Systeem tests automatiseren
Databases
08-04-2023NetWinst backend workflow56
Databases – situatie nu
Business Domain Classes
Domain classes Entity Classes Database
De database, het edmx data model en het business domain moeten constant in sync worden gehouden
Generated Entity classes
08-04-2023NetWinst backend workflow57
EDMX – Entity Data Model
08-04-2023NetWinst backend workflow58
EDMX – Entity Data ModelEen EDMX file bestaande uit 3 delen• storage schema definition language (SSDL)• conceptual storage definition language (CSDL)• mapping specification language (MSL)
Op basis van dit model worden C# entity classes gegenereerd zodat op objectgeorienteerde wijze met de database tabellen gecommuniceerd kan wordenDe programmeur is verantwoordelijk voor het koppelen van deze “data containers” aan de bijbehorende domeinclass.
08-04-2023NetWinst backend workflow59
Werkwijze – Database firstToevoegen nieuw veld aan databaseUpdaten van de EDMXToevoegen veld aan domein classKoppelen van het nieuwe veld in de domein class aan het nieuwe veld in de gegeneerde data class
08-04-2023NetWinst backend workflow60
Code First Model gebaseerd op domeinclasses i.p.v. databaseDatabase wordt automatisch gegenereerd/geüpdate op basis van wijzigingen in het domeinOp basis van conventiesSimpel in opzet, volledige controle wanneer nodigGeen gegenereerde code meerGeen EDMX meer Database revisiesProject binnenhalen staat gelijk aan database binnen halenMogelijkheid om op basis van de revisies SQL scripts te genereren, ideaal voor het aanpassen van een database die al live staat
08-04-2023NetWinst backend workflow61
Databases – Code First
Business Domain
Code
08-04-2023NetWinst backend workflow62
Werkwijze – Code FirstWijzigen business domeinToevoegen migratie (revisie)Update database
08-04-2023NetWinst backend workflow63
Update-Database
08-04-2023NetWinst backend workflow64
Update-Database -Script Update-Database -Script -SourceMigration: $InitialDatabase
Versiebeheer
08-04-2023NetWinst backend workflow66
SubversionCentraal versiebeheerSnapshots van je project door de tijdVerschillende takken (branches)De “ trunk” is de hoofdtak, hier gebeurd het implementeren van nieuwe functionaliteitNa wijzigingen doet een programmeur een commit van een of meerdere bestandenDit resulteert in een nieuwe revisie in de tak waar gewerkt wordtJe kan altijd terug naar een oude revisie
08-04-2023NetWinst backend workflow67
Subversion - voorbeeld
08-04-2023NetWinst backend workflow68
Subversion - probleem
1 jan 2 jan 3 jan 4 jan
1. 2 jan: “Deze functionaliteit wil ik zo snel mogelijk live hebben”
2. Release van revisie 2 op test3. Testers aan de slag + eventuele
bug fixing4. Ondertussen werken Joe en Eve
verder aan nieuwe functionaliteit
5. 4 jan: “Prima, zet maar live!”6. Oeps, er zit nu functionaliteit in
die nog niet getest is en ook nog niet live mag
7. Of nog erger, de punten van Joe en Eve zijn complex en liggen nog open!
08-04-2023NetWinst backend workflow69
Subversion – oplossing
1 jan 2 jan 3 jan 4 jan
Branch release r21. 2 jan: “Deze functionaliteit wil ik zo
snel mogelijk live hebben”2. Release van revisie 2 op test3. Maken van een nieuwe branch o.b.v.
de main trunk4. Testers aan de slag + eventuele bug
fixing (binnen de branch)5. Ondertussen werken Joe en Eve
verder aan nieuwe functionaliteit in de trunk
6. De branch en de trunk zijn twee onafhankelijke takken
7. Bij akkoord kan een release gedaan worden van de branch op de live server
8. Nu is het een kwestie van de branch weer samen te voegen met de trunk
08-04-2023NetWinst backend workflow70
Subversion – oplossing
08-04-2023NetWinst backend workflow71
Subversion – tagsTags en Branches zijn functioneel gezien hetzelfde, maar…Branches worden gebruikt voor doorontwikkeling op een aparte takTags zijn read-only branches voor iedere release die live gezet wordt. (versie 1.2 etc.)
Concreet voor NetWinst
08-04-2023NetWinst backend workflow73
Wat betekent dit hele verhaal concreet voor netwinst?
Er is één project wat leidend is, het startpunt voor ieder project. Het Master Project.Als je een fundamentele wijziging door wilt voeren in een van de componenten, gebeurd dat eerst in het master project, vervolgens dienen alle projecten op basis van het master project hierop te worden aangepast
08-04-2023NetWinst backend workflow74
Het Master Project - lagen
74
Web UI (ASP.NET MVC 4)
Service Layer
Business Domain
Data Layer
Unit Tests
08-04-2023NetWinst backend workflow75
Het Master Project - componenten
75
Web UI (ASP.NET MVC 4)
Service Layer
Business Domain
Data Layer
Unit Tests
Copernica Component Login Component Formulier Component
08-04-2023NetWinst backend workflow76
Het Master Project als startpunt
Master Project
Project 1 Project 2 Project 3
08-04-2023NetWinst backend workflow77
OptimalisatieHoe kunnen we een wijziging van een component in het master project automatisch laten doorvoeren in een child project?Hoe kunnen we voor een bepaald child project specifieke componenten aan en uit zetten?En hoe kunnen we een nieuw aan het master project toegevoegd component op simpele wijze toevoegen aan een al bestaand child project?
08-04-2023NetWinst backend workflow78
NuGet package manager
08-04-2023NetWinst backend workflow79
NuGet package managerEen package is een combinatie van files (html, code, etc.)Een package kan met een klik in de NuGet package manager geïnstalleerd worden in het projectDe package manager houdt ook de versie bij. Met één klik op update is je package weer helemaal up to dateEen package leent zich uitstekend voor een component (wat in feite ook een verzameling files is)
08-04-2023NetWinst backend workflow80
SubversionDevelopen in trunkTesten en bugs fixen in een branchBij een release naar live een tag aanmaken voor die versieGoed nadenken over inhoud commit• Meerdere kleine punten• Complexe punten apart• Altijd een omschrijving toevoegen• Niet iedere file apart commiten (elke commit is een nieuwe
revisie)
08-04-2023NetWinst backend workflow81
Unit testsCode schrijven met unit tests in het achterhoofdUnit tests schrijven die alle nodige situaties dekken• Let op “nodige”, geen triviale dingen
Goed omschrijvende namen geven en tests orderenen op basis van welke functionaliteit deze testenVoor bugs die na het testen terugkomen meteen een unit test schrijven en fixen
08-04-2023NetWinst backend workflow82
DatabasesIn de trunk, in een aparte map, moet altijd een SQL script met up to date testdata staan.Alle programmeurs werken via de werkwijze op de volgende pagina, op deze manier zijn conflicten uitgeslotenEr hoeven geen backup’s meer heen en weer gestuurd te worden. Het installeren van de database is nu een kwestie van twee simpele stappen.• Update-Database aanroepen in Visual Studio• Uitvoeren SQL script met testdata
08-04-2023NetWinst backend workflow83
Werkwijze Code First in een teamThis method works like:
Pull down the latest Domain Model into a branch.Turn on Automatic Migrations.Develop, Develop, Develop.Blow away your Development Database (and with it your __MigrationHistory table, and it’s state)Turn automatic migrations offPull the latest trunk/master Domain Model from your Source Control repo up into your branch.Merge the latest Domain Model with your local changes.Add a new migration of “the difference” between the repo and your domain model.Test a migration “up” on your local DB.Merge your branch back into your mainline.
Wrap up
08-04-2023NetWinst backend workflow85
Mooie code straalt wanneer…je dat ene wijzigingsverzoek 3 dagen eerder af hebt dan geplandje je als programmeur in ieder project meteen thuis voelter bijna geen bugs terugkomenje geen tijd meer kwijt bent aan repetitieve zakenje de unit tests op groen ziet springen en zelfverzekerd bent dat jouw code doet wat het zegteen uitbreiding of vervanging van code niet alles in de war gooit
08-04-2023NetWinst backend workflow86
en de developer straalt wanneer hij/zij
hierdoor…
True Zen
bereikt
één met
de code
Bedankt!
“Een dag niet gesaved is een dag niet geleefd.”
- Benno van Dijk
Vragen/discussie
The End