Wat is het .NET Framework nou eigenlijk?
Door Michiel van Otegem
10 augustus 2006
Wat is het .NET Framework nou eigenlijk?
Als je vraagt wat het .NET Framework eigenlijk is, krijg je van verschillende mensen
allerlei verschillende antwoorden. Zelfs Microsoft schijnt moeite te hebben met het
eenduidig beantwoorden van deze vraag. Gezien de grootte en de complexiteit van het
.NET Framework is dit niet echt verwonderlijk.
Bij het verschijnen van het .NET Framework is het door Microsoft gepresenteerd als
een "Web Services platform". Hoewel het zeer geschikt is voor het maken en gebruiken
van Web Services, is het .NET Framework veel meer. Het .NET Framework is ontwikkeld
om vele problemen op te lossen die we tegenkomen bij het ontwikkelen van moderne
applicaties. Moderne applicaties worden getypeerd door een aantal eigenschappen:
- Beschikbaarheid op ieder moment van de dag (24x7)
- Beschikbaarheid op allerlei locaties
- Uit te voeren op allerlei verschillende hardware
Voor applicaties met deze eigenschappen heeft Microsoft de .NET strategie bedacht, die
gevat wordt in de slogan "Anytime, anywhere, and on any device". Hoewel dit allemaal
erg triviaal klinkt, zul je zien dat er heel wat voor nodig is om applicaties te maken
waarvoor die eigenschappen ook daadwerkelijk gelden, zonder dat daarbij bijvoorbeeld
de veiligheid en performance van de applicatie ontoereikend zijn.
Om de .NET strategie te kunnen realiseren, moest Microsoft een rigoureuze stap nemen,
door de Windows-architectuur ten dele te vervangen. Windows leunt zwaar op het
Component Object Model (COM) en binaire communicatie tussen systeemonderdelen. COM
heeft echter meerdere eigenschappen die niet verenigbaar zijn met de .NET strategie.
In plaats van een houtje-touwtje oplossing om de tekortkomingen van COM te maskeren,
heeft Microsoft ervoor gekozen om een hele nieuwe architectuur te ontwikkelen: het
.NET Framework. Vooral voor ontwikkelaars betekent dit een hele stap, omdat ze een
groot deel van hun kennis van ontwikkeling op het Windows platform het raam uit kunnen
gooien. Je kunt weliswaar nog steeds applicaties maken op basis van COM, maar voor
nieuwe applicaties is het .NET Framework een stuk makkelijker, en zeker niet minder
krachtig. COM zal ook niet snel van de aardbodem verdwijnen, want de meeste Windows
applicaties vandaag de dag maken er gebruik van. Bovendien kunnen de onderdelen van
Windows die er gebruik van maken niet zo maar vervangen worden. Met de komst van het
.NET Framework zijn die onderdelen er nog wel, maar is er een beter alternatief. In
feite is het .NET Framework een omhulsel voor het operating systeem, dat ontwikkelaars
kunnen gebruiken om moderne applicaties te maken, zoals je kunt zien in het schema
Figuur 1.
Figuur 1, Schematische weergave van het .NET Framework
Bovenop het operating systeem draait de Common Language Runtime (CLR), die
verantwoordelijk is voor het uitvoeren van applicaties. Code wordt dus niet meer
direct door de processor uitgevoerd, en is ook niet meer gecompileerd naar machinetaal
(zoals bij COM). Code wordt gecompileerd naar Microsoft Intermediate Language (MSIL),
welke tijdens het uitvoeren van de applicatie Just-In-Time (JIT) gecompileerd wordt
naar machine taal. Hierbij verzorgt de CLR het geheugenbeheer, controleert het of de
code wel veilig is, en controleert het bovendien of de applicatie wel de juiste rechten
heeft om de gevraagde operaties uit te voeren (zie Figuur 2 hieronder).
Code die door de CLR wordt uitgevoerd wordt ook wel Managed Code genoemd, door alle stappen die de CLR verricht.
Je zou verwachten dat deze extra stappen de performance van een applicatie schaden,
maar het tegendeel blijkt waar. Tijdens de JIT compilatie wordt de code dusdanig
geoptimaliseerd voor het onderliggende operating system en de onderliggende processor,
dat deze extra stap niet uit maakt. Bovendien gebeurt JIT compilatie slechts eenmalig,
en wordt de resulterende machinetaal meestal meerdere malen gebruikt. Hoewel
ontwikkelaars zelf MSIL zouden kunnen schrijven (zoals ontwikkelaars ook assembler
voor een bepaalde processor kunnen schrijven), is dat helemaal niet nodig. Ontwikkelaars
kunnen werken met talen die gecompileerd worden naar MSIL. Hierbij kunnen ze momenteel
kiezen uit ruim 20 talen, waarvan C#, C++, JScript, J# (de Java taal), en Visual Basic
.NET, beschikbaar zijn van Microsoft, en in de meeste gevallen standaard beschikbaar
zijn. Al deze talen voldoen aan de Common Language Specification (CLS), een gemeenschappelijke
basis die er voor zorgt dat de talen met de zelfde gegevenstypen werken. Door de manier
waarop dit werkt kan een applicatie geschreven worden in meerdere talen, en kunnen
ontwikkelaars dus werken met de taal die ze het prettigst vinden. Een ander effect van
de manier waarop de CLR en CLS in elkaar zitten, is dat ze niet op Windows hoeven
werken, maar in principe op ieder platform kunnen draaien. Microsoft heeft dit bewezen
door een Shared Source implementatie te maken van een deel van het framework die werkt
op Windows XP, FreeBSD en MacOS 10.2 (zie http://msdn.microsoft.com/net/sscli). Deze
Shared Source implementatie omvat de Common Language Interface (CLI) en de programmeertaal
C#, en is gebaseerd op de specificaties die Microsoft daarvoor heeft ingediend bij de
ECMA voor standarisatie (zie http://msdn.microsoft.com/net/ecma/). Inmiddels heeft de
ECMA deze standaarden geratificeerd (hetgeen betekent dat Microsoft er niets meer aan
kan wijzigen zonder toestemming van de ECMA, waar onder andere IBM, Intel, Sun, en
Microsoft zelf onderdeel van uitmaken), en is er nu zelfs een standaardisatieproces
gaande bij de International Organization for Standarisation (ISO).
Zoals gezegd betekent het .NET Framework een hele verandering voor ontwikkelaars.
Hoewel je vaak in je geliefde programmeertaal kunt blijven werken, is er vooral veel
veranderd in hoe operaties moet doen die je voorheen met behulp van COM deed. Voor
deze operaties moet je nu gebruik maken van de classes in de Base Class Library. Dit
is een zeer omvangrijke bibliotheek met allerlei functionaliteit, bijvoorbeeld voor
het werken met een database, netwerk functionaliteit, en nog veel meer. De bibliotheek
is gelaagd opgebouwd, zodat je zoveel of zo weinig aan de bibliotheek over kan laten
als je zelf wilt. De Base Class Library is in principe de basis voor iedere soort
applicatie, of dit nu "gewone" applicaties zijn of webapplicaties die je in een browser
opent. In het eerste geval praten we over WinForms applicaties, en in het tweede geval
over ASP.NET applicaties, die uiteen vallen in webapplicaties en Web Services. Beide
vormen van applicaties hebben eigenschappen, die nu aan bod komen, die de .NET strategie
werkelijkheid moeten maken.
24x7 beschikbaarheid
Een applicatie, of deze nu draait op een server of op een desktop computer, die 24x7
werkt is de utopie van de computerwereld. Niet alleen betekent dit dat de applicatie
zelf foutloos (of eigenlijk fouttolerant) moet zijn, maar deze eis wordt ook gesteld
aan het onderliggende operating systeem en de hardware. Een bijkomend probleem is dat
aanpassingen aan een applicatie meestal betekenen dat de applicatie stilgelegd moet
worden, omdat er bestanden vervangen moeten worden die de applicatie nodig heeft. In
de meeste systemen zijn deze bestanden zolang de applicatie werkt afgesloten, en dus
niet te vervangen tot de applicatie is afgesloten. Hetzelfde probleem doet zich ook
voor met updates voor het operating systeem en het vervangen van hardware. Hoewel
sommige updates uitgevoerd kunnen worden zonder dat de machine opnieuw opgestart hoeft
te worden, en sommige hardware als de machine aan staat verwisseld kan worden, blijft
dit een zwak punt waar weinig aan te doen valt. Aan de server kant (die erg belangrijk
is voor het "anywhere" gedeelte) van een applicatie is een cluster of web farm een
oplossing die soelaas biedt, maar vaak tegen extreem hoge kosten.
De vraag is nu: hoe brengt het .NET Framework hier verbetering in? Aan de problematiek
met de hardware kan het .NET Framework niets veranderen. Alleen slimmere hardware kan
dat. Het .NET Framework kan er echter wel voor zorgen dat web farm oplossingen goedkoper
worden. Het doet dit door standaard ondersteuning te bieden voor het delen van
applicatiestaat tussen meerdere servers. Voor Windows servers had je hier voorheen
software van derden nodig, of moest je zelf een systeem ontwikkelen, met alle kosten
van dien. In ASP.NET kun je kiezen tussen applicatiestaat die opgeslagen wordt in het
geheugen van een aparte state-server, of applicatiestaat die opgeslagen wordt in een
SQL Server database. Vooral die laatste is een zeer robuuste oplossing, maar heeft wel
de nodige performance overhead, omdat een database nu eenmaal langzamer is dan geheugen.
Maar wat als we de state-server moeten updaten? ASP.NET heeft ook daarvoor een ingenieuze
oplossing. Als je iets wijzigt aan een applicatie, wordt parallel naast de lopende applicatie
een nieuwe applicatie opgestart die de wijzigingen gebruikt. Alle nieuwe gebruikers
vanaf dat moment worden afgehandeld door de nieuwe applicatie, en de oude applicatie
wordt pas afgesloten als alle gebruikers daarvan klaar zijn. Hierdoor kun je een nieuwe
state-server neerzetten, alle servers in de web farm aanpassen zodat de applicatie de
nieuwe state-server gaat gebruiken, en vervolgens wachten tot de oude applicatie klaar
is voordat je de oude state-server aanpast. Dit is natuurlijk een omslachtige operatie,
maar deze zal ook niet vaak voorkomen. Het mechanisme dat deze "wisseltruuk" mogelijk
maakt is ook in eerste instantie hier niet voor ontwikkeld, maar wel voor het zonder
meer kunnen aanpassen van lopende applicaties.
ASP.NET gebruikt een vergelijkbaar mechanisme om te zorgen dat een applicatie niet
crasht. Een ASP.NET applicatie wordt uitgevoerd door meerdere "worker threads". Deze
threads worden constant gecontroleerd door ASP.NET. Als een thread teveel geheugen
verbruikt of het er op lijkt dat deze is vastgelopen, start ASP.NET een nieuwe thread
op om het werk over te nemen. De oude thread wordt vervolgens gestopt, zodat deze de
stabiliteit van de rest van de applicatie niet kan aantasten. Op Windows 2000 en
Windows XP werkt ASP.NET onafhankelijk van Internet Information Services (IIS), zodat
zelfs problemen daarmee niet van invloed zijn op een ASP.NET applicatie. In Windows
.NET Server maakt IIS zelf gebruik van dit robuuste mechanisme, zodat in theorie IIS
zelf ook niet kan crashen. In Windows .NET Server maakt ASP.NET daarom standaard
gebruik van IIS om de stabiliteit te waarborgen, maar kun je er nog steeds voor kiezen
om ASP.NET in een apart proces te draaien. Alle maatregelen die ASP.NET neemt om
applicaties stabiel te houden staan los van voorzorgsmaatregelen van de CLR. Doordat
de CLR .NET code controleert en het geheugenbeheer daarvan doet, is die code al enorm
stabiel, maar in een serveromgeving is het dermate belangrijk dat de applicatie stabiel
blijft dat hiervoor dus extra maatregelen getroffen zijn.
Beschikbaarheid op allerlei locaties
Beschikbaarheid op allerlei locaties is eigenlijk het minste probleem van de .NET
strategie. Het internet is wijd verbreid en draadloze technologie zoals WiFi en GPRS
beginnen steeds gewoner te worden. Aan de hardware zal het dus niet zozeer liggen of
een applicatie op allerlei locaties beschikbaar is. Een veel belangrijker aspect is
de manier waarop een applicatie beschikbaar is, zeker als de verbinding met het netwerk
weg zou kunnen vallen. Een webapplicatie bijvoorbeeld is leuk, maar als je geen
netwerkverbinding hebt, heb je niets aan die applicatie. In zo'n geval is het handiger
om te werken met een applicatie die lokaal werkt, maar met gegevens van het netwerk,
die wanneer nodig (en mogelijk) bijgewerkt worden. Dit vereist een iets andere opzet
dan traditionele client-server applicaties, waarbij er een constante verbinding is
tussen de client en de server. Bovendien is de kans groot dat de applicatie via het
internet werkt, en door de beperking van firewalls gebruik zal maken van HTTP, waardoor
een constante verbinding met de server sowieso al niet mogelijk is. Het .NET Framework
biedt voor dergelijke applicaties twee methodes voor communicatie tussen de client en
de server: Remoting en Web Services. Welke van de twee je nodig hebt hangt af van de
situatie. Web Services zijn volledig gebaseerd op de standaarden SOAP en WSDL, en zijn
daardoor geschikt voor communicatie met ieder systeem dat deze standaarden ook
ondersteunt. Dit betekent dat de client of de server niet perse gebaseerd hoeft te
zijn op het .NET Framework. Het nadeel van Web Services is vooralsnog de inefficiëntie
van de gegevensoverdracht. Remoting gaat veel efficiënter om met bandbreedte, en er kan
bovendien meer mee dan met Web Services. Als zowel de server als de client het .NET
Framework ondersteunen is Remoting dus de meest voor de hand liggende oplossing. Een
van de grote voordelen van het .NET Framework is dat het gebruik van Remoting of Web
Services de complexiteit voor de ontwikkelaar nauwelijks vergroot. Of bepaalde gegevens
nu echt op dezelfde machine staan of bepaalde functionaliteit daadwerkelijk op dezelfde
machine wordt uitgevoerd is voor de ontwikkelaar niet van belang. De ontwikkelaar hoeft
slechts aan te geven welke externe functionaliteit gebruikt moet worden, en vervolgens
kan met die functionaliteit gewerkt worden alsof ze op de lokale machine aanwezig is.
In het .NET Framework zitten voorts meerdere classes die rekening houden met
gedistribueerde gegevens en het niet altijd beschikbaar zijn van een gegevensbron.
Hierdoor kunnen gegevens lokaal gebruikt worden en gesynchroniseerd worden wanneer de
daarvoor benodigde verbinding er is. Door de faciliteiten van het .NET Framework wordt
het ontwikkelen van gedistribueerde multi-user applicaties bijna net zo eenvoudig als
het ontwikkelen van single-user applicaties op een desktop.
Een andere problematiek van gedistribueerde applicaties is het bijwerken van de clients
wanneer er een nieuwe versie van de applicatie is, helemaal als dit transparant voor
de gebruiker moet gebeuren. In een internetomgeving is de effectiviteit van bijvoorbeeld
Systems Management Server enorm beperkt, dus moet hiervoor een alternatief zijn. Het
.NET Framework lost dit op door applicaties als download aan te bieden. Hierbij hoeft
de gebruiker de applicatie niet zelf te installeren, dit gebeurt automatisch op het
moment dat de gebruiker de applicatie via een download link start. Dit kan allemaal
gemakkelijk, omdat componenten van een applicatie onder het .NET Framework niet
geregistreerd hoeven te worden. De applicatie hoeft slechts te weten waar het de
benodigde componenten kan vinden. Is een applicatie eenmaal geïnstalleerd, dan
controleert het zelf (volgens regels opgegeven door de ontwikkelaar) of er nieuwe
versies van onderdelen van de applicatie beschikbaar zijn. Als er nieuwe onderdelen
zijn, worden deze automatisch en transparant voor de gebruiker bijgewerkt. Bij deze
aanpak zit er nog wel een addertje onder het gras, omdat applicaties kwaadaardig zouden
kunnen zijn. Een applicatie dus zonder meer uit voeren zou geen goed idee zijn. Dit is
waar de CLR een belangrijke rol speelt. Zoals eerder gezegd, verifieert de CLR of de
rechten van de applicatie wel toereikend zijn om bepaalde operaties te mogen uitvoeren.
Deze rechten kunnen afhangen van de gebruiker die een applicatie uitvoert, maar ook van
de locatie waar de applicatie vandaan komt. Een applicatie die bijvoorbeeld van het
internet af wordt gehaald heeft geen toegang tot gegevens op de lokale machine. Zou de
applicatie proberen gegevens van de lokale machine te halen, dan wordt deze afgesloten
en wordt de gebruiker op de hoogte gesteld van de overtreding. Hierdoor is het veilig
om dergelijke applicaties lokaal uit te voeren. Dit mechanisme, dat sandboxing wordt
genoemd, werkt op basis van Code Access Security, waarin een ontwikkelaar eventueel
ook van te voren kan opgeven welke rechten een applicatie nodig heeft. Blijkt bij het
opstarten dat de rechten niet afdoende zijn, dan kan de applicatie vragen aan de
gebruiker of het toegang mag hebben tot bepaalde systeembronnen (mits de gebruiker
hierover kan beslissen natuurlijk). Dit alles kan verder gedefinieerd worden op basis
van beveiligingsprofielen die een systeembeheerder kan opstellen.
Werken op verschillende hardware
Bij het werken op verschillende hardware moet je denken aan machines die niet gebaseerd
zijn op een Intel processor, maar eigenlijk meer nog aan andere soorten hardware,
zoals mobiele telefoons, PDA's, of bijvoorbeeld je autoradio. Een computer met een
andere processor is namelijk maar een klein probleem. Doordat MSIL code door de CLR
vertaald wordt naar machinetaal, is het betrekkelijk eenvoudig om een applicatie te
laten werken op een andere processor. Dit vereist slechts een aanpassing aan de CLR,
zodat deze werkt op een andere processor. Zoals eerder al gezegd is de kern van het
.NET Framework platform onafhankelijk, dus is het slechts een kwestie van manuren om
het over te zetten op een ander platform. Mobiele telefoons, PDA's en andere gadgets
zijn echter essentieel anders. Het meest voor de hand liggende probleem is de grootte
van het scherm, en de mogelijkheden daarvan. Een gebruikersinterface van een applicatie
moet dus anders opgebouwd worden. Een bijkomend probleem is dat vrijwel iedere telefoon
of PDA andere capaciteiten heeft. Als je dus een applicatie ontwikkelt voor telefoon
A, is de kans groot dat deze niet goed werkt op telefoon B. ASP.NET pakt dit probleem
aan door te detecteren wat de capaciteiten van de client zijn. Dit werkt uitstekend
met verschillen tussen browsers zoals bijvoorbeeld Internet Explorer en Netscape,
waarvoor op detailniveau verschillende HTML gegenereerd wordt zonder dat de
ontwikkelaar daar iets aan hoeft te doen. Dit zelfde mechanisme is voor mobiele
applicaties nog veel verder uitgebreid aan de hand van speciale controls. Hierdoor
wordt bijvoorbeeld een keuzelijst op een mobiele telefoon heel anders weergegeven dan
op een PDA. Op de telefoon kun je kiezen middels de cijfertoetsen, terwijl je met een
PDA de pen kan gebruiken. Ondanks deze grote verschillen, hoeft de ontwikkelaar de
applicatie maar één keer te maken en hoeft hij (tot op een zekere hoogte) geen
rekening te houden met wat voor client de applicatie gebruikt wordt. Het nadeel is
dat deze methodiek zich beperkt tot webapplicaties, en er dus niets lokaal uitgevoerd
wordt. Voor die functionaliteit heeft het .NET Framework een klein broertje: het
Compact Framework. Hierin zit alleen de hoognodige functionaliteit, zodat het ondanks
de beperkte opslagcapaciteit van een PDA toch kan werken.
Conclusie
Het .NET Framework is een zeer uitgebreid en robuust platform voor het ontwikkelen
van moderne applicaties. Het lijkt er vooralsnog op dat aan alle eisen is voldaan om
er een nieuwe generatie van applicaties op te kunnen ontwikkelen. Microsoft lijkt
daarmee voorbereid op de toekomst, en lijkt bovendien het stigma van onbetrouwbare en
onveilige software van zich af te schudden door hier grotendeels al in de architectuur
mee af te rekenen.
Dit artikel is eerder verschenen in Windows & .NET Magazine Benelux, maart 2003 (huidige naam NetOpus)
|