maandag 26 mei 2008

Afgelopen vrijdag was het mijn beurt om ook eens naar de DevDays te gaan. Ik had mezelf redelijk goed voorbereid door al een paar weken vantevoren de sessies op te schrijven waar ik heen wilde gaan. De sessies die mij het meest interessant leken waren:
1. Data protection with .NET Framework 3.5 and Cryptography Next Generation (Rafal Lukawiecki)
2. Is LINQ your data access layer? (Anko Duizer)

3. Understanding ADO .NET data services (Mike Taulty)

4. More intelligent applications using data mining (Rafal Lukawiecki)

5. Leveraging C#3.0 and LINQ (Best practice) (Krishnan Subramanian)

De ene sessie leek me wel leuker als de andere, maar dat blijf je toch houden.

Gelukkig stonden er afgelopen vrijdag nagenoeg geen files richting Amsterdam RAI, dus was ik nog net op tijd om de eerste sessie te volgen.

Rafal begon hier eerst met een ‘basis’ van cryptografie. Voor m’n MCTS examen heb ik hier ook het een en ander voor moeten leren, dus de basis begreep ik redelijk goed. Hij had het over wat momenteel de meest veilige manier was om je applicatie te beveiligen, bijvoorbeeld met smart cards. Ook noemde hij nog de twee functies ProtectData en ProtectMemory die je zeker moet kennen als je heel eenvoudig stukken code van je applicatie wilt beveiligen. Deze twee functies zijn beschikbaar vanaf versie 2.0 van het .Net Framework.
Vanaf versie 3.5 van het .Net Framework zijn er echter veel betere encryptie methoden beschikbaar. Verder kwam er nog een lijstje met methoden die je nu nog wel en niet meer mag gebruiken voor encryptie.
Het wel lijstje bestond uit:
Rijndael / AES 128
RSA 3072

SHA-2 (als het moet)
DSA

Wat je niet meer moet gebruiken is:
DES (Kerberos)
IDEA
RC2 / RC5
Blowfish, Twofish (nou ja, deze zijn wel goed, maar niet standaard)

Ook noemde hij nog 2 functies welke je tegenwoordig kunt gebruiken voor encryptie. In het 3.0 Framework is dit bijvoorbeeld RijndaelManaged en het 3.5 Framework is de functie AesManaged geintroduceerd. Van wat ik begrepen heb zijn het beide implementaties van Rijndael.

Dit bovenstaande was echter nog maar het begin en er waren ook nog maar 20 minuten voorbij. Het leek trouwens wel alsof Rafal aan speed-talking deed zo snel ging het.
Nu begon het moeilijke gedeelte van de sessie. Hij begon ineens over Suite-B, een ‘nieuwe’ encyryptie methode welke onder andere is ontwikkeld door de NSA. De NSA zelf maakt gebruik van Suite-A wanneer iets boven het level ‘top-secret’ komt. Hierop maakte hij nog de opmerking dat Suite-B dus eigenlijk helemaal niet zo veilig was, maar gewoonweg het beste was wat er momenteel door het publiek kan worden gebruikt.
Suite-B maakt gebruik van ‘Elliptical Curve Cryptography’. Dit houdt in het kort in dat het sneller is, je hebt minder bits nodig en is minstens zo veilig als ‘oude’ methoden met meer bits. Vanaf dit moment werd het me allemaal een beetje te technisch en heb ik het niet meer zo goed kunnen volgen.
Wel heb ik nog een aantal aantekeningen kunnen maken van de stukken die ik wel snapte, maar het hele Suite-B verhaal heb ik zelf een beetje overgeslagen.

Tegen het einde aan noemde Rafal nog dat het gebruik van hashes helemaal niet zo veilig meer is, als je dit tenminste voor cryptografie wilt gebruiken. Hij stelde voor om een heel bericht te encrypten en dat dan te gebruiken als ‘hash’. Het nadeel hiervan is dat wanneer je een bericht van 1GB hebt, je ook een ‘hash’ van 1GB hebt.

Ik was blij dat dit bijna het einde was van die sessie, zodat ik even kon bijkomen van wat hij allemaal te zeggen had.
Een kort filmpje van de sessie is op Tweakers.net te vinden: http://tweakers.net/advertorials/devdays/video/20/data-protection-with-net-frameworks-35.html

De tweede sessie was voor mij al een stuk eenvoudiger om te volgen. Zelf ben ik namelijk al een tijdje bezig met LINQ te implementeren in m’n data access layer, dus was ik wel benieuwd wat anderen hiervan vonden.
Anko vertelde hier over de twee verschillende maniere hoe je L2SQL kunt gebruiken in je n-tier applicatie. Ten eerste als data layer en ten tweede als toevoeging in je data layer.

De eerste methode ben ik zelf niet zo’n enorme fan van. Het kwam er op neer dat je je dbml-bestand als DAL gebruikt en zo dus gelijk (in welke laag dan ook) je wijzigingen kunt wegschrijven. Hij gaf zelf ook al aan dat dit meestal niet echt gewenst is, aangezien je overal in je project DA code hebt staan en je bij wijzigingen dus je gehele project moet doorlopen. Het was daarentegen wel snel te implementeren.

De tweede methode, L2SQL gebruiken [b]in[/b] je DAL, vind ik zelf de beste oplossing voor nu. Je kunt zo beter je objecten afstemmen op wat je wilt gebruiken in je applicatie en je hebt maar op 1 plek in project de DA code staan. Het kost echter wel weer meer tijd om te maken in vergelijking tot de eerste methode.

Tijdens deze sessie kwam ik nog enkele leuke opties tegen die je kunt gebruiken met L2SQL. Dit waren bijvoorbeeld de mogelijkheden om ContinueOnConflict te gebruiken, een soort On Error Resume Next, ResolveAll, om een soort rollback te doen en ChangeConflicts. Deze waren volgens Anko nodig omdat L2SQL er van uit gaat dat het opslaan goed gaat en dat hoeft natuurlijk niet zo te zijn, aangezien het systeem aan dirty-reading doet, sowieso wanneer je een n-tier applicatie hebt.

Zelf was ik het niet met Anko op alle fronten eens, maar daar was ik er ook voor, om te kijken wat andere ontwikkelaars nou precies vinden van L2SQL en hoe te gebruiken.

De derde sessie ging over ADO.Net. Dit vond ik een enorm leuke sessie om bij te wonen. Mike kon het allemaal goed vertellen en ik werd enorm enthousiast om dit systeem te gaan gebruiken in een van mijn projecten. Waar het in het kort op neer kwam is dat je via een soort webservice (via WCF) queries kon doen via je webbrowser. Niet alleen simpele queries, maar ook behoorlijk geavanceerde queries. Als je je data service enigszins goed opzet dan kun je via foreign keys zo alles opzoeken van iemand. Wanneer ‘medewerker y’ bijvoorbeeld enkele klanten heeft die op hun beurt orders hebben geplaatst bij het bedrijf waar ‘medewerker y’ werkt, dan kun je via de querystring in je browser alle orders opzoeken die bij ‘medewerker y’ zijn geplaatst. Ook kan er worden gegroepeerd en derdelijke. Dit werkt allemaal met collecties die AsQueryable zijn. Je wilt natuurlijk niet altijd via een browser naar informatie zoeken en aangezien de collecties queryable zijn, kun je ook met het Entity Framework of L2SQL/L2O je gewenste objecten zoeken. Ik vond dit de meest interessante sessie van de dag. Rodi zat ook bij deze sessie, hij zag echter gelijk al de nadelen van de methode die Mike aan het vertellen was. Een van die nadelen was het beveiligen van je WCF webservice. Dat kan natuurlijk niet en je wilt niet je hele data omgeving blootleggen aan de buitenwereld. Dit is zeker een valide punt om het niet te gebruiken. Misschien dat ze daar nog over na gaan denken, of dat hier al lang een oplossing voor is. De techniek is in ieder geval ontzettend gaaf. Enkele links met meer informatie die Mike nog gaf waren http://www.datadeveloper.net, http://www.miketaulty.com en http://blogs.msdn.com/astoriateam
De sites heb ik zelf nog niet bekeken, maar zodra ik weer eens tijd over heb zal ik dat zeker doen.

Mijn vierde sessie werd weer gegeven door Rafal, dit keer ging het over data mining. Eigenlijk wist ik niet precies wat ik moest verwachten, maar dat werd al snel duidelijk. Het ging er namelijk om dat door de gebruiker ingevoerde gegevens strookt met de werkelijkheid. Rafal gaf als een voorbeeld een formulier met soortgelijke gegevens als deze:

Naam: John
Geslacht: Female
Leeftijd: 900
Thuissituatie: Zoon van ouders

De Analysis Services van SQL Server geven nu een melding dat de gegevens waarschijnlijk niet kloppen. De leeftijd is bijvoorbeeld veel te hoog en het is onwaarschijnlijk dat iemand een vrouw is en tegelijk een zoon.

Deze onwaarschijnlijkheden worden niet zo uit de lucht gevist, maar worden berekend door Analysis Services aan de hand van honderden/duizenden/tienduizenden records die als verificatie dienen. AS vind namelijk patronen in die records en aan de hand daarvan berekend hij hoe waarschijnlijk het is dat de ingevoerde data klopt.

Het grote voordeel van dit systeem is dat je je logica voor een formulier niet meer zelf hoeft te maken, dat doet SQL wel voor jou. Dit scheelt uiteraard enorm veel ontwikkeltijd, omdat je dus niet meer tig if-statements hoeft te schrijven.

Het nadeel dat ik al snel kon bedenken is dat wanneer je een paar grapjassen hebt die een paar keer foute data in je database stoppen, je AS denkt dat dit valide is en op een gegeven moment dus niet meer meldingen geeft bij situaties als hierboven beschreven. Hier zul je dus alsnog alert om moeten zijn.

Dit is dus een leuke techniek, maar ik denk niet dat je het nu al kunt gebruiken in een productie omgeving bij een druk bezochte website.

De laatste sessie die ik heb gevolgd ging weer over LINQ en C# 3.0. Deze sessie vond ik wel iets interessanter dan die van Anko eerder die vrijdag. Je kon wel merken dat Krishnan een ontwikkelaar is en geen vertegenwoordiger of iets dergelijks, dat hoop ik tenminste, want het ontbrak hem een beetje aan presentatie skills. Dat geeft verder niet, want z’n verhaal was wel goed. Hij gaf enkele voorbeelden hoe je je partial methods kunt gebruiken met LINQ. Zelf gebruik ik die ook al, maar met de hij gaf ook als voorbeeld om de OnValidate functie te gebruiken in je partial method. Hier had ik zelf nog niet aan gedacht, maar is wel een goede suggestie. Je kunt dan tijdens het valideren al zien of de data in een object wel of niet juist is.
Ook gaf hij een mooie oplossing om N:N-relaties te maken met L2SQL. Officieel kan dit niet, maar hij gaf er een mooie work-around voor. Hierdoor heeft hij wel wat credits van me gekregen. Wat wel jammer is, is natuurlijk dat hij de gegevens alleen maar ophaalde uit de database en niet weer terug schreef. Echter, zal het in de praktijk waarschijnlijk niet vaak voorkomen dat je in 1 mutatie N:N inserts wilt doen, dus op zich was het wel te begrijpen. De oplossing die hij gaf was om een property te maken van IEnumerable en die in je partial class te zetten waar je dat object in wilde hebben. Dit was wel een goed idee van hem waar ik zelf nog niet aan had gedacht, dus was het toch ook weer nuttig om deze sessie bij te hebben gewoond.
Om je query dynamisch te maken maakte hij gebruik van [i]predicates[/i] in de where-clause van je L2SQL query. Dit is niet gelijk fout natuurlijk, maar het geniet toch mijn voorkeur om hiervoor echt Lambda expressies te gebruiken, waar ik al eerder over heb geschreven ( http://www.jan-v.nl/ViewPost.aspx?PostID=aeb2009d-2624-dd11-afa4-003048874dd5 )
Een filmpje van een eerdere sessie van Krishnan is hier te vinden: http://tweakers.net/advertorials/devdays/video/21/linq-trekt-volle-zaal!.html
De mensen in het commentaar daar vinden hem een goede spreker, nou ja, meningen kunnen verschillen natuurlijk. Wat ze wel goed opmerken is dat het goed is dat hij live code klopt, je zou dit ook als nadeel kunnen opmerken trouwens.

Op zich was ik blij dat de dag voorbij was, want het was toch zwaarder dan ik had verwacht. Al met al heb ik behoorlijk wat informatie opgedaan. In eerste instantie ga ik waarschijnlijk niet gelijk met alles aan de slag, maar het is wel goed om het in het achterhoofd te houden. Op naar volgend jaar!

Donderdag is MartinS op mijn pas geweet en vrijdag was het dan eindelijk mijn beurt om een bezoekje te plegen aan de DevDays van dit jaar. De eerste sessie die ik op het programma had staan was van Alex Thissen over het ASP.NET MVC Framework. MVC staat voor Model-View-Controller en is een interessant design pattern waar Microsoft dus een eigen Framework voor aan het bouwen is. Dit Framework is nog niet af en kan in details nog wel veranderen, maar je kon er een goede indruk van krijgen. Omdat ik verkeerd was gelopen en aan de andere kant van de RAI bij een andere sessie uitkwam, kon ik geen plaatsje meer veroveren en moest ik de hele sessie staan. Mede daarom heb ik ook geen aantekeningen gemaakt.

Als je gebruik maakt het MVC Framework, gooi je een hele hoop functionaliteit de deur uit en kun je niet meer vertrouwen op de Page Lifecycle; Page_Load en andere (postback) events zul je niet meer op de normale manier gebruiken; veel Server Controls werken niet. Een request komt binnen op de Controller, die bepaalt wat er precies gevraagd wordt en zorgt dat de juiste gegevens worden uitgewisseld met het Model om vervolgens de juiste View (pagina/aspx) op te starten en gegevens aan mee te geven. Een Request gebeurt wel met een mooie url in de zin van: www.mijnwebsite.nl/Artikel/Edit/67. Deze ‘routes’ zijn helemaal te configureren met standaard waarden voor elk onderdeel uit de url en wat al niet meer, nu nog in de global.asax, maar wellicht straks ook in de Web.config. Wat wel een grote drempel voor mij en vele andere ASP.NET ontwikkelaars zal zijn, is dat de View (de aspx) erg veel gaat lijken op oude asp. Je ‘for loopjes’ komen tussen de html te staan en je maakt zelf je html op; wel zijn er veel hulpfuncties om html te genereren voor bijvoorbeeld dropdowns en textboxen, maar het wordt toch weer de ouderwetse wirwar van code en html. Een van de grootste voordelen die altijd worden genoemd, is dat dit design pattern de testbaarheid van je presentatielaag velen malen groter maakt en het wordt dan vaak ook aangehaald in combinatie met TDD (Test Driven Development), hoewel daar ook wel Model-View-Presenter voor wordt gebruikt, een iets andere variatie op MVC. Om dit te benadrukken wordt een MVC project in Visual Studio altijd automatisch voorzien van een testproject.

De vraag blijft staan of dit Framework toegepast moet/kan worden in toekomstige projecten of niet. Sommige projecten zijn minder geschikt dan andere en er zal een grote omschakeling moeten komen van de ontwikkelaars. Wat de keuze nog moeilijker maakt, is dat het design pattern zo cool is en dat het heel goed bijdraagt aan ‘Seperation of Concerns’, dus het scheiden van code met elk een ander doel in de applicatie.

De tweede sessie had als titel ‘Is LINQ your Data Access Layer’ en werd gepresenteerd door Anko Duizer. Wederom was ik te laat voor een stoel, maar hier kon je redelijk relaxed achteraan op de grond hangen en toch nog wat volgen. Twee stellingen werden er voorgelegd: LINQ to SQL is de DAL en LINQ to SQL wordt gebruikt in de DAL.

Als LINQ to SQL (vanaf nu gewoon LINQ voor het gemak) de DAL is, dan zal eventuele business logica ook in deze laag moeten zitten en is het dus eigenlijk twee lagen in één. Voordelen zijn o.a. simpel en snel om te gebruiken, dus goed voor RAD, binding is heel goed geregeld. Nadelen zijn o.a. dat er nagenoeg een 1 op 1 mapping is tussen Relationele DB structuur en Object structuur in code en dat je dus een mix krijgt van Presentatie, Business en Data Access. De uitbreidingen die je maakt (business logica) zijn wel mooi weg te stoppen in Partial Classes/Methods. Van 1 tabel met een soort Type-veld is het mogelijk om obv dat veld onderscheid te maken en er een base-class van te maken met meer dan één afgeleide classes (BaseUser -> Author en Publisher).

Als LINQ wordt gebruikt in de DAL zul je een betere scheiding kunnen realiseren, maar is er ook veel meer werk nodig. Voordelen zijn o.a. dat je een echte DAL hebt, dat je een betere mapping hebt naar je eigen Domain Model (Business Entiteiten / Information Packages), dat het mogelijk is om nog te switchen naar andere techniek, omdat het een eigen laag is. Nadelen zijn o.a. dat er veel meer code nodig is en dus veel meer tijd zal kosten; bovendien moet er veel meer nagedacht worden over bepaalde obstakels die je zal tegenkomen. Omdat alles in een DataContext zit opgesloten is het lastig om de objecten naar de Presentatielaag te serialiseren en weer terug te deserialiseren. Hier zijn 3 methoden voor: LNQ to SQL Entities (de meest simpele), POCO’s (Plain Old CLR Objects, meeste werk, maar ook meest clean door gebruik van eigen Domain Model / Information Packages) en DataSets (veel support, maar ook beperkingen). Normaal wordt gebruik gemaakt van Deferred Loading, wat inhoud dat er pas iets uit de DB wordt gehaald op het moment dat je het in je code (in een loop bijvoorbeeld) nodig hebt. Dat is na serialisatie naar de Presentatielaag natuurlijk niet meer mogelijk, dus je moet van te voren bepalen wat je nodig hebt: heb je bijvoorbeeld alleen de Orders nodig of wil je ook alle Orderregels erbij hebben?

Algemeen zijn er nog wat opmerkingen te maken. LINQ to SQL is standaard optimistisch qua concurrency, wat inhoudt dat je zelf conflicten moet afhandelen als Dirty Reads e.d. Het is mogelijk om een cache mismatch te krijgen, doordat de DataContext los van de database staat. Een gebruiker zal dan vreemde resultaten te zien krijgen.

Het antwoord op de vraag die in de titel van de sessie wordt genoemd, is niet anders te beantwoorden dan met iets als: “Het kan, maar het hangt ervan af.” Als je je eigen Domain Model wilt behouden, dan moet je het gebruiken in je DAL en kan het niet de DAL zijn. Wat je je dan wel goed moet afvragen, is of LINQ to SQL je dan voordeel oplevert t.o.v. gewoon ADO.NET. In mijn eigen beleving is dit niet het geval, zeker niet als je je bedenkt dat we al een hele opzet hebben voor een DAL. Het voordeel van LINQ to SQL zou dan vooral zijn dat er heel veel wordt gegenereerd en je dus minder (steeds weer dezelfde) code hoeft te schrijven.

Na de lunch stond “Understanding ADO.NET Data Services” op het programma. Dit gaat over een tegenhanger van Web Services en worden ook wel RESTful Services genoemd. Data Services gaat volledig over http en maakt gebruik van het pure http-protocol. Het is dus geen SOAP. WCF kan onderliggend gebruikmaken van REST en van SOAP, dus je blijft de keuze houden; Microsoft gooit SOAP niet weg na zoveel investeringen.

Elk soort data kan gebruikt worden over deze Data Services. Ophalen van gegevens is eenvoudig, maar voor een update moet er veel moeite gedaan worden. In het toekomstige Entity Framework zal een ObjectContext beschikbaar zijn; als je daarvan gebruik maakt is ook het updaten weer eenvoudig geworden.

Wat erg mooi is, is dat je je volledige datasource al kan zien/testen via de url van je browser. Je krijgt dan alles wat je opvraagt (inclusief query-achitge zaken als top, startpositie, filter etc.) in XML. Ook in de code is het erg makkelijk om een query te schrijven tegen een Data Service; dit is zelfs mogelijk met LINQ: de LINQ query wordt dan vertaald naar een Data Service query. En wat ook erg handig en makkelijk is, is dat dit ook erg eenvoudig vanuit Javascript is te doen, dus voor AJAX.

De vierde sessie was moeilijk te kiezen, want eigenlijk spraken de titels me allemaal niet aan. Ik heb gekozen voor Parallel Extensions to the .NET Framework, gepresenteerd door een echt grappige kerel: Daniel Moth. Deze Extensions zijn nog in de maak en er is nu pas een eerste openlijke beta/ctp uit; het enige wat zeker is, is dat het niet dit jaar uitkomt. Ook zullen wij er als Web Developers niet veel mee te maken krijgen. In het begin stonden er quotes op het scherm die we konden lezen; wel interessant wat men denkt over de toekomst van normale desktops pc’s: meer Hz is niet goed meer te doen door de beperkingen in koeling van de chips; in de laatste twee jaar zijn we daardoor heel snel al naar Quad cores gegaan voor de normale consument. Volgens de wet van Moore verwachten ze dat we binnen tien jaar al mainstream pc’s hebben met 80 cores (dat hoeft niet perse 1 cpu te zijn natuurlijk). Het is daarom belangrijk om je te richten op het efficiënt gebruiken van de cores. De Parallel Extensions moeten dat makkelijker gaan maken. Het biedt een laag niveau API dat je niet hoeft te gebruiken, maar wel beschikbaar is en twee meer bruikbare/simpele API’s die daarop gebouwd zijn. De ene is slimmer dan de Thread Pool class, maar minstens zo uitgebreid en bruikbaar als de Thread class, de tweede is een uitbreiding op LINQ en kan LINQ query’s heel makkelijk uitbreiden voor multiple cores.

De laatste sessie was: “Leveraging C#3.0 and LINQ (Best Practice)”, en beetje saai en de spreker probeerde grappig te zijn, maar was het niet. Misschien lag het ook deels aan mijzelf, maar ik kon mijn gedachten er niet goed bijhouden. Toch heb ik nog wel een paar dingen genoteerd. Voor de rest kun je bij JanV zijn, want die heeft deze sessie ook gevolgd.

Met Partial Classes kun je goed uitbreiden. Wil je in LINQ op een mooie manier n op m relaties leggen (dus relaties die een koppeltabel nodig hebben), dan kun je zelf een property maken in de ene class die een List van e andere teruggeeft. De getter van de property loopt dan door de ‘koppeltabel’ heen om de juiste items terg te geven. Het is ook mogelijk om met een extra property enkele properties samen te voegen in 1 nieuwe property van een eigen type. Als je bijvoorbeeld adresgegevens los hebt staan in een tabel, dan kun je deze private maken in LINQ. Vervolgens kun je een Adres-Class maken en een nieuwe property van het type Adres. In het adres geef je dan de afzonderlijke (private) adresgegevens terug.

In LINQ is paging standaard ingebouwd! Je doet in een LINQ query gewoon heel gemakkelijk “.skip(x).take(y)” om x items te skippen en vervolgens y items op te halen. LINQ zal er dan zelf voor zorgen dat de meest optimale query wordt uitgevoerd. In SQL2005 zal dit vaak met ROW_NUMER() zijn (behalve op de eerste pagina (optimaal dus)) en in SQL 2000 zal de query een stuk ingewikkelder zijn. Het mooie is dus dat je daar zelf niets meer mee te maken hebt.

Al met al was het dus een interessante dag. Ik vond het minder dan vorig jaar, maar misschien komt dat doordat er vorig jaar nog allemaal spannende onbekende nieuwe dingen waren die heel erg uitgebreid belicht werden, maar er nog niet waren. Nu ging het vooral wat dieper op de dingen in de nu al uit zijn, maar dan soms ook weer niet diep genoeg, niet met de juiste uitgangspunten (voor mij) of een beetje te chaotisch (zoals de laatste sessie). Maar dat betekent niet dat het geen geslaagde dag was; ik heb toch weer wat geleerd.