Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28...

72
Nummer 102 september 2009 SDN Magazine verschijnt elk kwartaal en is een uitgave van Software Development Network www.sdn.nl IN DIT NUMMER O.A.: Azure .Net Services < HierarchyID in SQL Server 2008 < Introduction to Language Integrated Query with Delphi Prism < Windows Sidebar Gadgets Ontwikkelen met Silverlight 2.0 < Spell Check in SharePoint 2007 < SOFTWARE DEVELOPMENT NETWORK MAGAZINE 102 19 & 20 OKTOBER A.S. SDN CONFERENCE Papendal, Arnhem SCHRIJF NU IN!

Transcript of Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28...

Page 1: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

Nummer 102 september 2009 SDN Magazine verschijnt elk kwartaal en is een uitgave van Software Development Network

www.sdn.nl

IN DIT NUMMER O.A.:

• Azure .Net Services <

• HierarchyID in SQL Server 2008 <

• Introduction to Language Integrated Query with Delphi Prism <

• Windows Sidebar Gadgets Ontwikkelen met Silverlight 2.0 <

• Spell Check in SharePoint 2007 <

SOFTWARE DEVELOPMENT NETWORK

MAGAZINE

102

19 & 20 OKTOBER A.S.

SDN CONFERENCEPapendal, Arnhem

SCHRIJF NU IN!

Page 2: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

Advertentie Macaw

Page 3: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

magazine voor software development 3

ColofonUitgave:

Software Development NetworkZeventiende jaargangNo. 102 • september 2009

Bestuur van SDN:

Remi Caron, voorzitterRob Suurland, penningmeesterJoop Pecht, secretarisMark Vroom, vice-voorzitter

Redactie:

Rob Willemsen ([email protected])

Aan dit magazine

werd meegewerkt door:

Maurice de Beijer, Rolf Craenen, Anko Duizer, Marcel van Kalken, Stefan Kamp-huis, Marcel Meijer, Mirjam van Olst, JohanParent, Joop Pecht, Sandra de Ridder,Maarten van Stam, Bob Swart, Mariannevan Wanrooij, Rob Willemsen en natuurlijkalle auteurs!

Listings:

Zie de website www.sdn.nl voor eventuelesource files uit deze uitgave.

Vormgeving en opmaak:

Reclamebureau Bij Dageraad, Winterswijkwww.bijdageraad.nl

©2009 Alle rechten voorbehouden. Niets uitdeze uitgave mag worden overgenomen opwelke wijze dan ook zonder voorafgaandeschriftelijke toestemming van SDN. Tenzijanders vermeld zijn artikelen op persoonlijketitel geschreven en verwoorden zij dus nietnoodzakelijkerwijs de mening van het be-stuur en/of de redactie. Alle in dit magazinegenoemde handelsmerken zijn het eigen-dom van hun respectievelijke eigenaren.

AdverteerdersMacaw 2VNU 20Barnsten/Embarcadero 27Bergler 28Microsoft 36-37Alladdin 41Sybase iAnywhere 454DotNet 52Sogeti 63Avanade 71Bridge Incubation Group b.v. 72

Adverteren?

Informatie over adverteren en de adverten-tietarieven kunt u vinden op www.sdn.nlonder de rubriek Magazine.

voorwoordDe zomereditie van het SDN-magazine ligt voor je: klaar voor gebruik en je hebt vast vol-doende tijd om het tot de laatste letter door te nemen. B.v. omdat je vakantie hebt en na heteten lekker in de tuin van het zonnetje zit te genieten of op het strand zit of op je bootje rond-dobbert op het strakblauwe water. Of omdat het op kantoor toch een fractie minder druk isdan een jaar geleden en je die tijd goed kunt gebruiken om je kennis weer helemaal up-to-date te brengen.In beide gevallen vind je genoeg van je gading om weer helemaal mee te gaan tellen. Er wordteen groot aantal nieuwe versies, functionaliteiten en zelfs talen voorgesteld. Van SQL Server2008 worden b.v. de nieuwe HierarchyID en de Sparse columns voorgesteld.De Azure .Net Services worden voorgesteld. Hiermee krijg je een omgeving tot je beschikkingvoor het draaien van applicaties en het opslaan van gegevens in Microsoft data centra, diezich overal ter wereld kunnen bevinden. Je kunt applicaties maken die je daar laat hosten,maar je kunt er ook voor kiezen bestaande applicaties te verrijken met individuele services die– en let op, daar komt een modern toverwoord - in de “Cloud” draaien.

Delphi Prism krijgt ook uitgebreid aandacht. Eerst presenteert Bob Swart nieuwe features alsAsyncs, Futures & Parallels, waarmee hij maar wil laten zien dat Delphi for .NET niet langer“achterloopt” op het gebied van .NET features, maar juist nu al gebruik maakt van functio-naliteit die nog niet eens (volledig) beschikbaar is in .NET. Een geluid dat ook wel eens gehoordmag worden! En we hebben een artikel van de hand van Cary Jensen waarin hij een intro-ductie van LINQ – de Language Integrated Query – in Delphi Prism geeft, iets dat we in .NETal langer kennen.

Nog meer nieuwigheden in een artikel over F#, een nieuwe taal uit de Microsoft-stal. Aardigom te lezen - maar ook wel even wennen! – over een functionele taal als tegenhanger voorde imperatieve talen waar de meesten van ons gewend zullen zijn om mee te werken. Overigens gebiedt de eerlijkheid om te zeggen dat F# eigenlijk van beide walletjes snoept …En last but not least wil ik nog een artikel uit de User Experience hoek vernoemen dat een onderwerp behandelt waar vast ook nog niet iedereen zijn handen aan ‘gebrand’ heeft, nl. hoeje Windows Sidebar Gadgets kunt ontwikkelen die met Silverlight 2.0 werken, incl. het uitrollen daarvan. Al met al genoeg nieuws … en dan hebben we nog een stuk of 8 (!) artikelen onvernoemd gelaten. Niemand hoeft zich dus te vervelen in de zomer van 2009.

Wat je in dit magazine ook terugvindt is de blik op de aankomende SDN Conference die 19& 20 oktober gehouden wordt op Papendal (Arnhem), tegelijk met de DotNetNuke Open-Force '09 Europe conferentie. Je kunt er in dit magazine haast niet om heen: het programma,voor zover bekend op het moment van drukken, wordt gepresenteerd, maar via talloze ‘post-its’ proberen we het event en de datum in je geheugen te prenten. Want als je dit jaar dan tochwilt gebruiken om weer helemaal up-to-date te geraken, dan moet je naar de SDN Conference2009 komen … natuurlijk!

Veel leesplezier!Rob Willemsen,[email protected]

PS: Wellicht ten overvloede vermeld ik nog even dat we in dit magazine de lijn doortrekken die in

de vorige editie- de WIT-special: Women In Technology – wel heel expliciet gemaakt is, nl. dat

vrouwen ook heel goed in de IT uit de voeten kunnen … of liever artikelen van hun hand kunnen laten

zien. We presenteren opnieuw een (flink aantal) artikelen van vrouwelijke hand; niet allemaal, zoals

vorige keer, maar we hebben toch weer 4 vrouwelijke auteurs die acte de présence geven!

Page 4: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

SDN CONFERENCE2 DAYS SOFTWARE DEVELOPER CONFERENCE

19 & 20 OKTOBER 2009

PAPENDAL, ARNHEM

Inhoud03 VoorwoordRob Willemsen

04 Inhoudsopgave

05 Azure .Net ServicesJacqueline van der Holst

09 DevTweetMarianne van Wanrooij en Sander Hoogendoorn

10 SDN Conference

14 The WebHub Way of ThinkingAnn Lynnworth

21 Silverlight en Open SourceKoen Zwikstra

24 HierarchyID in SQL Server 2008André van ’t Hoog en Arjan Pot

29 FloraHolland Moderniseert Hart ITNorbert Mimpen

31 Under the Hood: Provider-Based Authorization in DotNetNuke 5.1

Brandon Haynes

34 Delphi Prism: Async, Futures en Parallele Mogelijkheden

Bob Swart

38 Spell Check in SharePoint 2007Gustavo Velez

42 Fun met Webparts in ASP.Net - Deel 2User Controls en Webparts

Bert Dingemans

46 Introduction to Language Integrated Query with Delphi Prism: Part 1

Cary Jensen

49 Interesting Things: Creative PlumbingSander Hoogendoorn

50 Sparse Columns in SQL Server 2008 Bert Dingemans

53 De Kick Ass Development ReeksFreek Leemhuis en Maarten Metz

57 Agenda

58 ASP.NET onder de Motorkap:Ben jij al AJAX supporter?

Michiel van Otegem

59 Requirements Managementvoor Software Architecten

Marion Verwey en Nienke van de Brink

64 F#: Een Functionele Oplossing binnen een Imperatieve Wereld

Laurens Ruijtenberg

67 Windows Sidebar Gadgets Ontwikkelen met Silverlight 2.0

Fons Sonnemans

Page 5: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

.NETC# Jacqueline van der Holst

Microsoft .Net services bestaan uit een set services voor developersen een SDK om .NET applicaties in de “Cloud” te kunnen draaien. Jekunt aan .Net services denken als een nieuw .Net framework maardan specifiek voor dit type applicaties. Dit framework bestaat uit ser-vices, die gebaseerd zijn op standaard protocollen, zodat elk serviceplatform erop kan aanhaken. Denk daarbij aan SOAP, REST en WS*technieken. Wanneer je als developer gewend bent om te werken metWindows Workflow Foundation en Windows Communication Foun-dation, dan zul je het niet moeilijk vinden om met de .Net services SDKte werken. Wil je er direct mee aan de slag? Je kunt dan de SDKdownloaden van http://www.microsoft.com/azure en een code aanvragen om je eigen solution aan te kunnen maken.

Op dit moment bestaan de .Net services uit een drietal services voorhet regelen van connectiviteit, toegang en workflow, te weten:• Microsoft .Net Service Bus: een netwerk infrastructuur voor het

verbinden van applicaties over het Internet;• Microsoft .Net Access Control Service: op claims gebaseerde

toegang waarbij het kan werken met identity providers als ActiveDirectory en Windows Live ID;

• Microsoft .Net Workflow Service: een infrastructuur voor het managen en hosten van workflows.

Dit artikel beschrijft de Microsoft .Net Service Bus in combinatie metde Microsoft .Net Access Control Service.

Microsoft .Net Service BusIn de praktijk zien we dat het nog steeds een uitdaging is om appli-caties met elkaar te verbinden. Om dit mogelijk te maken gebruiken organisaties een Enterprise Service Bus (ESB). De Microsoft .Net Ser-vice Bus heeft een gelijkwaardige architectuur. Het verschil zit hem inhet blikveld en de probleemstelling. Immers de .Net Service Bus moetop een globaal internet niveau kunnen draaien en dat ook nog eensmet hoge inzet. Met de Microsoft .Net Service Bus kun je je huidigeESB verbinden met services die in de “Cloud” draaien, maar je kunt de.Net Service Bus ook inzetten om applicaties met elkaar te verbindendie zich op verschillende fysieke locaties achter een firewall bevinden.

ArchitectuurOm beter te kunnen begrijpen hoe de Microsoft .Net Service Buswerkt, is de architectuur ervan te zien in figuur 1. Hieronder wordenverschillende onderdelen van de architectuur besproken aan de handvan een listing.

Figuur 1

Om een applicatie in de “Cloud” te laten draaien moet je een nieuweAzure solution aanmaken op http://www.microsoft.com/Azure. Voordit artikel heb ik de solution AzureExample aangemaakt (zie figuur 2).

Figuur 2

In het voorbeeld gebruiken we een client project en een service project. Listing 1 toont het service contract en een operatie die tweeintegers verwacht. Listing 2 definieert de service die twee getallen metelkaar vermenigvuldigt. Hieronder wordt besproken hoe we deze

magazine voor software development 5

Azure .Net ServicesDe Microsoft .Net Service Bus en de Microsoft Access

Control Service gecombineerd

Afgelopen jaar kondigde Ray Ozzie op de Professional Developer Conference het Windows Azure Services Platform aan. Het Azure Services Platform is een omgeving voor het draaien van applicaties enhet opslaan van gegevens in Microsoft data centra, die zich overal ter wereld bevinden. Bedrijven kunnen ervoor kiezen om daar nieuwe applicaties te hosten, maar je kan er ook voor kiezen bestaandeapplicaties te verrijken met individuele services die in de “Cloud” draaien.

Page 6: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE6

service via de servicebus beschikbaar gaan maken en hoe we hemkunnen gaan gebruiken.

namespace Services{

[ServiceContract (Name="SampleContract", Namespace="http://azureexample.microsoft.com/ServiceModel/Relay")]interface ISampleContract{

[OperationContract]int Sample(int getal, int multiplier);

}}

Listing1

namespace Services{

[ServiceBehavior(Name="SampleService", Namespace="http://azureexample.microsoft.com/ServiceModel/Relay/")]public class SampleService: ISampleContract{

public int Sample(int getal, int multiplier){

return getal * multiplier;}

}}

Listing2

NaamgevingLaten we allereerst eens naar de naamgevingstrategie kijken. De basisvan het naamgevingsysteem is oplosbaar met traditionele DNS technieken. Het is aan de eigenaar van de solution om de hiërarchische namespace te controleren. De manier waarop je hetmoet indelen is als volgt:

[scheme]://[solution-naming-scope]/[name]/[name]

De naamgeving van de URI is onder te verdelen in een drietal onder-delen. De CTP release van november ondersteunt de schemes SB enHTTP, waarbij je HTTP gebruikt voor de op HTTP gebaseerde endpoints en SB voor alles wat anders is (bijvoorbeeld TCP). De solution-naming-scope beschrijft de solution binnen het Azure platform en bestaat uit

servicebus.windows.net/services/[solution]

Als laatste definieer je de endpoint namen. Alles wat na [solution] komtin het pad is onderdeel van de door de gebruiker gedefinieerde namespace. Je kunt een onbeperkte hoeveelheid endpoint namen opgeven door een hiërarchie van namen achter [solution] te plakkenin het pad. Voor het listing in dit artikel ziet de uri er als volgt uit:

sb://servicebus.windows.net/services/AzureExample/

SampleService

Twee verschillende services binnen de solution hoeven niet op dezelfde machine of in hetzelfde netwerk te worden gehost. Het is detaak van de Service Bus om te bepalen waar de endpoints zich bevinden.

Service RegistryNaast de naming convention biedt de Service Bus een Service Registry voor het publiceren en ontdekken van service endpoints binnen een solution. Dit kan zowel automatisch als handmatig. Hethandigst is om dit automatisch door de Service Bus te laten regelen.

//Definieer credentials. Username en //password van de solution.

TransportClientEndpointBehavior userNamePasswordServiceBusCredential =

new TransportClientEndpointBehavior();

userNamePasswordServiceBusCredential.CredentialType = TransportClientCredentialType.UserNamePassword;

userNamePasswordServiceBusCredential.Credentials.UserName.UserName = solutionName;

userNamePasswordServiceBusCredential.Credentials.UserName.Password = solutionPassword;

//Endpoint adresUri address = new Uri(String.Format("sb://{0}/services/{1}/SampleService/", ServiceBusEnvironment.DefaultRelayHostName, "AzureExample"));

ServiceHost host = new ServiceHost(typeof(SampleService), address);

// Voeg de credentials aan alle endpoints toeforeach (ServiceEndpoint endpoint

in host.Description.Endpoints){endpoint.Behaviors.Add(userNamePasswordServiceBusCredential);

}

// Open de hosthost.Open();

Console.WriteLine("Service address: " + address);Console.WriteLine("Press [Enter] to exit");Console.ReadLine();host.Close();

Listing 3

In listing 3 is te zien hoe we een endpoint adres aanmaken voor onzeSampleService. Voor authenticatie met de Service Bus worden deusername en het password gebruikt die je hebt opgegeven bij het aan-maken van de solution in Azure. Op basis van de configuratie (listing4) maken we een host aan. De credentials worden aan elk endpointtoegevoegd. In dit geval is dat er maar een, namelijk SampleService.Vervolgens wordt de host geopend (figuur 3).

Figuur 3

<?xml version="1.0" encoding="utf-8" ?><configuration>

<system.serviceModel><bindings>

<netTcpRelayBinding><binding name="default" />

</netTcpRelayBinding></bindings><services>

.NETC#

Page 7: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

magazine voor software development 7

<service name="Services.SampleService"><endpoint name="RelayEndpoint"

contract="Services.ISampleContract"binding="netTcpRelayBinding"bindingConfiguration="default"address="" /> </service>

</services></system.serviceModel>

</configuration>

Listing 4

De client applicatie is op een zelfde wijze geconfigureerd (listing 5) alsde service applicatie.

<?xml version="1.0" encoding="utf-8" ?><configuration>

<system.serviceModel><bindings>

<netTcpRelayBinding><binding name="default" />

</netTcpRelayBinding></bindings><client><endpoint name="RelayEndpoint"

contract="AzureSample.ISampleContract"binding="netTcpRelayBinding"bindingConfiguration="default"address="" />

</client></system.serviceModel>

</configuration>

Listing 5

RelayIn het hart van de Service Bus bevindt zich de Relay Service (figuur 4)om door firewalls en NAT heen te kunnen communiceren. De relaymaakt het mogelijk voor een zender om met een ontvanger te com-municeren door middel van een adres. In het code voorbeeld is dat

[sb://servicebus.microsoft.net/services/AzureExample/

SampleService]

Figuur 4

De ontvanger is door middel van een naar buiten openstaande poortverbonden met de Relay Service en specificeert het adres waarnaar hijwil luisteren. De zender kan dan een bericht verzenden door hetzelfdeadres te specificeren. Vervolgens kan de Relay Service het berichtdoorgeven aan de ontvanger die op hetzelfde adres zit. De ontvangerhoeft geen inbound poorten open te hebben staan.

De Relay Service ondersteunt de volgende messaging patronen:• One-way• Request/response• Peer-to-peer• Publish/subscribe scenarios

• Connection-oriented bi-directional socket communication.Wanneer je gebruik maakt van de Relay Service leg je de luisterver-antwoordelijkheid bij de Relay Service. Om gebruik te kunnen makenvan de Relay Service leg je een connectie tussen je lokale service ende Relay Service. Binnen .Net doe je dit door het WCF program-meermodel en -bindings die in de SDK zitten te gebruiken. Deze bin-dings worden dan omgezet naar nieuwe transport bindings om WCFlisteners te maken die met de Relay Service integreren. Voor de RelayService is het nodig dat een aantal outbound poorten open staan, teweten 808 (TCP connecties), 828 (TCP/SSL connecties) en poorten818 en 819 voor geavanceerde TCP connecties. Wanneer je binneneen omgeving werkt die alle outbound connecties blokkeert, behalvediegene die gebruikt worden door HTTP/HTTPS, dan kun je een speciale HTTP gebaseerde verbindingsoptie gebruiken.

De listing gebruikt de binding NetTCPRelayBinding aangezien Microsoft deze binding als default aanraadt. Hij is zeer efficiënt enmaakt een publiekelijk te bereiken endpoint aan in de Relay Service.Client applicaties moeten geconfigureerd worden met dezelfde binding. Deze binding ondersteunt drie soorten verbindingen:• Relay: alle communicatie gaat via de relay service;• Hybride: de initiële communicatie gaat via de relay service waarna

zender en ontvanger een directie communicatie met elkaar hebben.Deze communicatie wordt wel gecoördineerd door de relay service;

• Direct: zonder relay service. In de CTP werkt dit nog hetzelfde alsde hybride connectie.

Naast de binding getoond in bovenstaand voorbeeld, zijn er nog devolgende mogelijkheden:

Tabel 1: Relay bindings

De relay bindings werken ongeveer identiek aan de WCF bindings.Het is een uitdaging om te weten welke binding je exact nodig hebt.De NetTcpRelayBinding wordt als default aangeraden, maar je zou jekunnen voorstellen dat deze wellicht niet zou volstaan omdat out-bound TCP poorten nodig zijn voor de luisteraar. Je zou dan bijvoor-beeld de NetOnewayRelayBinding kunnen gebruiken. Deze is watagressiever en maakt gebruik van HTTP poorten 80/443 die meestalopen staan.

Een Relay Service werkt als een omgeving die compleet los staat vande lokale omgeving, wat het mogelijk maakt om ongewild verkeertegen te houden voordat het bij je service-omgeving uitkomt. Het verbergt ook alle informatie over de netwerklocatie.Het idee van een Relay Service is niet nieuw. Ook Groove gebruikt eenRelay Service voor het uitwisselen van documenten.

Authenticatie en autorisatieDe Microsoft .Net Service Bus vraagt van elke ontvanger om geauthenticeerd en geautoriseerd te zijn voor een specifieke URI,

Standaard WCF Binding Vergelijkbare Relay Binding

BasicHttpBinding BasicHttpRelayBinding

WebHttpBinding WebHttpRelayBinding

WSHttpBinding WSHttpRelayBinding

WS2007HttpBinding WS2007HttpRelayBinding

WSHttpContextBinding WSHttpRelayContextBinding

WS2007HttpFederationBinding WS2007HttpRelayFederationBinding

NetTcpBinding NetTcpRelayBinding

NetTcpContextBinding NetTcpRelayContextBinding

N/A NetOnewayRelayBinding

N/A NetEventRelayBinding

.NETC#

Page 8: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE8

voordat het een listener maakt voor die ontvanger. Dit geldt ook voorclients die willen dat de Service Bus berichten voor hen relayt, al kunje dat voor de client wel uitzetten wanneer je je endpoints configureert.Authenticatie kun je laten regelen door de Access Control Service.Vervolgens is het dan aan de Access Control Service om de claimsaan de .Net Service Bus te produceren voor autorisatie. Het verschiltussen authenticatie en autorisatie zit hem in wie je bent en wat je magdoen. De Service Bus is zo ontworpen dat het de Access Control Ser-vice vertrouwt. De Service Bus zoekt naar claims in de “security to-kens” die meegegeven worden door zenders en ontvangers. Er zijnmaar twee claims waarnaar gezocht wordt, namelijk #send en #listen.Wanneer die gevonden zijn en er is niet gerommeld met het security-token dan wordt toegang gegeven.

Wanneer een zender of ontvanger met solution credentials of met eensecurity-token op de proppen komt dan maakt de .Net Access Con-trol Service een rules gedreven beslissing of een autorisatie-tokenwordt afgegeven aan in dit geval de Microsoft .Net Service bus. De Ac-cess Control Service signt en encrypt het security-token zodat declaims alleen gelezen kunnen worden door de .Net Service Bus. Alleende Service Bus kan de informatie decrypten en lezen. Wanneer hetbericht richting de ontvanger gaat wordt het autorisatie-token verwij-derd. Dit heeft de ontvanger immers niet nodig.

De listing maakt gebruik van een managed card van de Security TokenService, welke bekend staat als Microsoft Identity Lab (https://ipsts.fe-deratedidentity.net/MgmtConsole/Default.aspx), waar een account isaangemaakt. Daarnaast moeten we voor de Access Control Servicenog wat aanpassingen maken aan de solution in Azure (http://por-tal.ex.azure.microsoft.com/default.aspx). Allereerst moeten we descope toevoegen aan de solution, waarbij je kiest voor de Service Bus.Vervolgens klik je op identity issuer en voeg je https://ipsts.federate-didentity.net toe. Binnen het lab is een account aangemaakt onder degroep Domain Users. Daarom wordt ook een claim type toegevoegdmet de naam Group en de waarde Domain Users. Wanneer je dannaar Rules gaat dan zie je dat er al een Send en Listen rule is aange-maakt. Daar maak je nog een extra rule aan om aan te geven dat dereceiver tot de groep Domain Users moet behoren. De servicebus au-thentiseert in listing 6 de client door Windows Cardspace informatie tegeven. Hier kun je aangeven, dat je verwacht dat het token een claim-type group heeft. Vervolgens wordt een channel geopend en kan deservice geconsumeerd worden.Tijdens het draaien van de code wordt om je credentials gevraagd(figuur 5).

Figuur 5

string serviceUserName = Console.ReadLine();

//AdresUri serviceUri = new Uri(String.Format("sb://{0}/services/{1}/SampleService/",ServiceBusEnvironment.DefaultRelayHostName, serviceUserName));

//Federatie via cardspaceTransportClientEndpointBehavior behavior = new TransportClientEndpointBehavior();

behavior.CredentialType = TransportClientCredentialType.FederationViaCardSpace;

behavior.Credentials.FederationViaCardSpace.ClaimTypeRequirements.Add(new ClaimTypeRequirement("http://ipsts.federatedidentity.net/group"));

EndpointAddress address = new EndpointAddress(serviceUri);

//ChannelChannelFactory<ISampleChannel> channelFactory =

new ChannelFactory<ISampleChannel>("RelayEndpoint",new EndpointAddress(serviceUri));

channelFactory.Endpoint.Behaviors.Add(behavior);

ISampleChannel channel = channelFactory.CreateChannel();channel.Open();

Listing 6

ConclusieDe .Net Service Bus is een veilige, op standaarden gebaseerde manier van het verbinden van applicaties over het internet. .Net Developers kunnen hun voordeel doen met de Service Bus door simpelweg te kiezen uit een geheel nieuwe set WCF-bindings. De restvan de WCF-code blijft eigenlijk hetzelfde. Op security vlak verbergt de Service Bus alle informatie over de net-werklocatie en biedt het een omgeving die compleet los staat van delokale omgeving. Op deze manier kunnen kwaadwillenden door deService Bus worden gestopt voordat het te laat is.Door de Microsoft .Net Service Bus en de Microsoft Access ControlService te combineren is het mogelijk om op een makkelijke en veiligemanier applicaties met elkaar te verbinden. Zelfs door firewalls heen.

LinksJe kunt alles vinden over dit onderwerp op http://www.microsoft.com/azure. Bekijk tevens alle presentaties over Azure ophttp://www.microsoft.com/pdc. •

Jacqueline van der Holst

Jacqueline van der Holst ([email protected]) is als consul-tant werkzaam bij Avanade, een samenwerkingsverband tussen Mi-cro soft en Accenture. Zij houdt zichbezig met onderwerpen als Share-Point, Azure, LINQ, Patterns andpractices.

.NETC#

Page 9: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

DevTweet: Software Development with a wink

DevTweet’s zijn de conversaties tussen Marianne van Wanrooij en Sander Hoogendoorn overde (on)zin die IT-ers bezig houdt: Software-ontwikkeling met een knipoog. Regelmatig zullenook gasten worden uitgenodigd. Volg ze ook op Twitter via @mariannerd en @aahoogendoorn!

Listening to Black Sabbath's Master of Reality.

@aahoogendoorn Look at you... new avatar! Is that an AC/DCshirt?

@mariannerd Howdy partner! It is AC/DC all right. Your avatar newtoo? Something wrong with the old one?

@aahoogendoorn Nope, just a change in scenery! Like the projectI'm doing. I'm asked to do a code review.

@mariannerd Cool! Whenever I'm asked to do a code review, theclient always knows, or at least suspects, something's terriblywrong.

@aahoogendoorn Oh yes... We have the suspect... Now it's a caseof getting the evidence ... I feel like Columbo..

@aahoogendoorn You know the suspects from the beginning, butyou still have to look for the evidence for conviction!

@aahoogendoorn So when you are asked to do a code review,what is the first thing you do?

@mariannerd The first thing I do? Ask the client what they're hopingto achieve: do they actually want to know how deep the rabbit holegoes?

@mariannerd Next, I make a list of all things I should look at duringthe review. Architecture, domain, data access, layers, extensibility..

@mariannerd Security, authorization, reuse, code copying (especi-ally in VB), way of working, documentation, design, quality of coding.

@aahoogendoorn So far so good!

@mariannerd Rule #1 in code reviews: more time means more detail.

@aahoogendoorn Code Reviews are fun! No deadlines. just lookingat somebody else’s code.

@aahoogendoorn ... Oh and telling what's wrong with it... I mustsay this is the first time I get such an assignment.

@mariannerd You know, there's so much horrible code out there,we could do code reviews for the rest of our lives.

@aahoogendoorn Well, a lot of this stuff is subject to opinion... 100 developers, 100x different code for the same functionality...

@mariannerd Yes true, but some code is definitely worse than othercode. And believe me, I've seen some bad coding in my time.

@aahoogendoorn Any examples?

@mariannerd Examples of bad code? How many do you need.Check out this old blog post of mine (in Dutch). http://htxt.it/reVB

@mariannerd Think of SQL statement in web pages, or of a singleclass that handles 50% of all functionality.

@mariannerd Or think of the same business rule implemented multiple times on different locations, in different ways.

@aahoogendoorn One of the things I came across: internal web application: authentication by doing a LDAP query to see if the userexists.

@aahoogendoorn Haven't they heard of Windows Authentication inIIS? They didn't even check if the user was enabled or disabled... :-S

@mariannerd Haha, nice one. I once audited the enterprise web portal for a very large international company where ALL communication ...

@mariannerd between front end and back end went through onesingle class. Imagine the effect of a single change..

@mariannerd Sometimes, it gets really bad. Code a whole companydepends on, which is so bad, that productivity will definitely bebelow zero soon.

@mariannerd Anyway, I love being asked for code reviews. It givesthe opportunity to help improve the quality of applications.

@mariannerd That is, if they follow up on your advice from yourcode review. Unfortunately, that is not always the case.

@aahoogendoorn Well maybe it's not needed... Or they just want to know the risks and are happy to take them!

@aahoogendoorn Which could be the outcome of a code review.It's not good, but far from worse… And it may be fixed with a coupleof quick wins.

@mariannerd Well yes, that could be the outcome. Maybe I'm toidealistic about writing good code. If it ain't broken, don't fix it.

@mariannerd But I just love clean code...

@aahoogendoorn .... But even bad code can function.

@mariannerd My favorite example: an ASP.NET web site that wasnever compiled by the developers. They just ran it from the browser.Great stuff!

@mariannerd As a consequence, of the over 40 pages in the application, only 6 compiled (the ones they visited running it in thebrowser)...

@aahoogendoorn LOL "we got a live one here!". This business application compiled at runtime? No test cases, just put it in production!

@mariannerd And then things can get pretty messy. Especiallywhen your poor company lives of this software.

@aahoogendoorn That is the whole point isn't it… Developers juststart coding without a plan, or knowing best practices.

@mariannerd Yes, a lot of developers code without having a decent architecture, without patterns, without layers - but with best intentions.

@aahoogendoorn Oh yes, best intentions... The road to hell ispaved with good intentions...

@mariannerd No stop signs, speed limits. Nobody's gonna slow medown. Highway to hell. AC/DC# ?

@aahoogendoorn Nope... 4 minutes by Madonna LOL.

@mariannerd Madonna? Girl you need a music review instead of acode review!

@aahoogendoorn ....I guess even bad music can function. ;-)

Highway to hell? @mariannerd and @aahoogendoorn reviewing code of the boys

magazine voor software development 9

Page 10: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

• .NET (C#, VB, etc.)

• User eXperience

(ASP.Net, Silverlight, Expressions, Flash, etc.)

• Information Worker (MOSS, BizTalk, OBA, etc.)

• DotNetNuke (OpenForce Europe ’09 Conference)

• Delphi

• Core Systems

• Databases

• Architecture

• General topics

2 DAYS SOFTWAREDEVELOPMENTCONFERENCE 200919 EN 20 OKTOBER 2009 PAPENDAL, ARNHEM

.

Also included:

19 & 20 OKTOBER A.S.

SDN CONFERENCEPapendal, Arnhem

SCHRIJF NU IN!

Page 11: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

S o f t w a r e D e v e l o p m e n t N e t w o r k , Po s t b u s 5 0 6 , 7 1 0 0 A M W i n t e r s w i j k Te l : 0 5 4 3 - 5 1 8 0 5 8 w w w. s d n . n l

SDN leden betalen € 595,- voor deelname,niet-leden betalen € 695,-

EEN ALL-IN PRIJSHet SDN is een No Nonsense Club, dus geen “verrassingen” achteraf. De prijsis duidelijk en “All-In”, dus mét consumpties in de pauzes, mét lunch (2x) enmét diner op maandagavond. Zelfs het parkeren is inbegrepen! Wie wil overnachten in het hotel van Papendal (een aanrader!) kan bij het aanmelden meteen een hotelkamer boeken. Wees er wel snel bij want het aantal beschikbare kamers is beperkt.

Daarom is er het Software Development Network!

Page 12: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINEMAGAZINE

.NETRichard Campbell CAN Performance Tuning ASP.NET (Understanding Performance Tuning)Stephen Forte USA Building RESTful Applications with Microsoft Tools

Data Access Hacks and ShortcutsRobert Green USA WCF and WF: Two Great Technologies That Go Well Together

An Introduction to Windows Communication FoundationWindows Communication Foundation Security Fundamentals

Chad Hower CYP ADO.Net Entity FrameworkASP.Net MVC Framework

Nik Kalyani USA Hands-on Windows Azure: Building a Twitter CloneBeth Massi USA Future Directions for Microsoft Visual Basic and C#

Taking Advantage of LINQ and XML in Office 2007Ted Neward USA The Busy .NET Developer's Guide to DSLs in OsloDennis van der Stelt NL VelocityShawn Wildermuth USA Building your first MGrammar

Data Validation in Silverlight 3Why Oslo Matters

overzicht sprekers en sessies

Architecture Kent Alstad CAN Queuing with Azure

The Great Database in the SkyFrom iPhone to Azure

Richard Campbell CAN From One Web Server to Two: Making the LeapUdi Dahan IL Intentions & Interfaces - Making Patterns Concrete

Avoid a Failed SOA - Business & Autonomous Components to the RescueDesigning High Performance, Persistent Domain Models

Sander Hoogendoorn NL Modeling services using smart use casesApplying model driven development in developing Silverlight 2.0 applications

Michael Stiefel USA How To Partition and Layer a Software ApplicationClaims Based Security: What it is and Why it will be in your FutureDoes the Relational Database Make Sense in the Cloud?Architecting Software as a Service

DelphiMarco Cantù I Creating Windows 7 Applications in Delphi

Multi-Threading in DelphiDomain Specific Languages in Delphi

Pawel Glowacki NL Delphi Natural InputHadi Hariri SP ASP.NET MVC in Delphi Prism

Advanced ASP.NET MVC in Delphi PrismChad Hower CYP Connecting to .NET with CrossTalk

IntraWeb: Then, Now, and FutureCary Jensen USA Introduction to WPF Development with Delphi Prism

An Introduction to LINQ in Delphi Prism9 Thread Synchronization Options in Delphi Compared

Barry Kelly USA Delphi Compiler RTTI EnhancementsDesign of a combined garbage-collection and serialization mechanism

Bob Swart NL Delphi 2010 DataSnap Enhancements

User eXperienceNik Kalyani USA Raising the UX Bar with ASP.NET MVC and jQueryDon Kiely USA AJAX 4.0: Rich Internet Applications Come of Age

Revenge of the Client: AJAX 4.0 Data BindingJoost Nuijten NL De ultieme gebruikerservaring

Rich Internet ApplicationsKlaasjan Tukker NL Building rich internet applications with Flash Builder and .NET

Interactive video expierencesShawn Wildermuth USA Building Behaviors in Silverlight 3

Page 13: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

DatabaseCary Jensen USA Advantage Database Server and Delphi: A Perfect MatchDon Kiely USA SQL Server 2008 Security for Developers

User-Defined Types and Aggregates in SQL Server 2008Dick Moffat CAN Using Microsoft Access 2010 With SharePoint

The new features of Microsoft Access 2010

overzicht sprekers en sessies

Erik van Ballegoij NL Leverage the DotNetNuke framework for your own applicationCathal Connolly UK DotNetNuke performance tips & tricks

DotNetNuke and Dynamic DataAuditing and logging - Who, what and when?

Peter Donker NL Advanced Module DevelopmentExtension software protection in DNN

Steve Fabian USA WCF and DotNetNukeWindows Workflow and DotNetNukeTemplating : User-Controlled Output

Nik Kalyani USA Advanced Skinning with DotNetNuke 5Using and Extending the DotNetNuke Widget Framework

Stefan Kamphuis NL DotNetNuke 101 for ASP.NET DevelopersVicenç Masanas SP Using MSBuild to automate building and packaging

Creating a SiteMap provider for DotNetNukeCharles Nurse CAN DotNetNuke in the Cloud

DNN and .NET v4Module Development Chalk and Talk

Shaun Walker USA DotNetNuke LocalizationDotNetNuke ProfessionalDotNetNuke State of the union

DotNetNuke OpenForce ‘09 Europe

Information Worker / SharePointNick Boumans NL Social Networking in SharePoint

E-Commerce using SharePoint and Commerce Server 2009Donald Hessing NL SharePoint and Jquery

Integratie Silverlight en SharePointBeth Massi USA Building Office Business Applications with Visual StudioDick Moffat CAN Excel Development - Rules of EngagementWouter van Vugt NL Localizing SharePoint Solutions

Developing SharePoint Workflows

GeneralRichard Campbell CAN Death of a Web Server: Crisis in CachingSander Hoogendoorn NL Do’s and don’t in implementing and applying extension methodsDennis van der Stelt NL Introduction into the TDD Mantra

Making sense of the buzz words

Core SystemsScott Ambler USA RUP: Agile Development

Agile Development WorkshopMartin Knobloch NL Security Advanced

The Secure development lifecycleTed Neward USA Effective Enterprise Java

A Tour of the Open Source Java Community

Page 14: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

DELPHI Ann Lynnworth

When the developer sees the sketch, he or she could realize that onlytwo variables are needed to make that section work for any company.At that point, the sketch would be copied to a droplet, expecting twoparameters, as shown in Listing 3:

<whdroplet name="drBanner"><whdoc for="drBanner">DYN1 – name of image used for the logoDYN2 – company slogan/textUsage: call via web action named 'waBanner'</whdoc><table id="banner"><tr><td><img src="/sitedesign/(~DYN1~)" /></td><td>(~DYN2~)</td>

</tr></table></whdroplet>

Listing 3: A droplet, expecting two parameters to fill in variable data

The developer could then make a web action to find the data and display it. There are many approaches. Listing 4 shows how it can bedone by calling the PARAMS command, which runs a droplet, passingin parameters.

useswebApp;

procedure TForm1.waBannerExecute(Sender: TObject);varOrgImageFilename: string;OrgSlogan: string;

begin// do some database lookup to find these valuesOrgImageFilename := 'abc.jpg';OrgSlogan := 'A.B.C. Company, the best since 1885';

pWebApp.SendMacro(Format('PARAMS|drBanner|%s,%s',[OrgImageFilename, OrgSlogan]));

end;

Listing 4: Web action component loads data then calls the drBanner droplet, passing two parameters which become availableas DYN1 and DYN2)

When that was in place, most likely the Delphi programmer would disable the sketch by changing show="yes" to show="no", and adding(~waBanner.execute|~)

MAGAZINE14

The WebHub Way of ThinkingThis is part 2 of the article published in magazine 101.

How Exactly does a Team Cooperate?The user manual for the WebHub extension for Dreamweaver discusses the topic of team cooperationin great detail, and includes best-practice advice for file organization, naming conventions, and so on (seehttp://www.href.com/edeliver:whdw). Nonetheless, I can give you an overview here now. We have alreadytalked about the fact that the WHTEKO files are kept separate from the WebHub application. Generally,a graphic design person would be given access to those files, plus the images, css and javascript files.All such files can be easily maintained in version control.

Refreshing when files changeIf the designer changes an image or a CSS file, reloading the webpage in the browser should be enough to see the change. If the designer changes a WHTEKO file and wants to see the effect ina web browser (without using Dreamweaver), he or she needs to getthe WebHub application to refresh. There are many ways to do this,including using WebHubAdmin on the server, right-clicking and selecting Refresh from the tray menu of the running app on the server,or using a browser to trigger a special page with a refresh commandfor this purpose. I find that using the browser is usually quickest.The special page would be declared as shown in listing 1,

<whpage pageid="remoterefresh">

(~app.refresh~)

</whpage>

Listing 1: A page used to tell the app to reload WHTEKO and config details

and called from Firefox or IE using

http://www.mydomain.com/scripts/runisa.dll?appid:remoterefresh

Of course, you might add security to make sure the remoterefreshpage was only called from certain ip numbers or only on a restrictedsubdomain.

From sketch to actualA designer often needs to put in some placeholder content, beforethe Delphi programmer can create a perfect web action to generatethe content dynamically. WebHub supports this process with a<whsketch_tag>. Listing 2 shows an example, where part of a pagebanner is built.

<whsketch show="yes">

<table id="banner">

<tr>

<td><img src="/sitedesign/ABCCompanyLogo.png" /></td>

<td>A.B.C Company … the best, since 1885 </td>

</tr>

</table>

</whsketch>

Listing 2: A sketch, showing sample data in position, for design purposes

Page 15: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

magazine voor software development 15

DELPHI

Once that was in place, the designer could make further adjustmentsto the drBanner droplet (listing 3) to add CSS tags, etc., independentlyfrom the Delphi programmer.The <whdoc_tag> in listing 2 is optional. We recommend using it whenever droplets expect parameters, so that everyone knows whatis required. In some future version of WebHub, we hope to make theweb action components more self-documenting, so that they could report their usage automatically. For now, coders should use the<whdoc_tag> or a WebHub comment to annotate tricky sections ofthe file.

Text Substitution MacrosWebHub supports unlimited text substitution macros. The restrictionson macros is that each must fit on one line (but that can be a longline). A droplet, by contrast, can include unlimited lines. Listing 5 showsimaginary macros.

<whmacros>mcAssetRoot=/files/mcLegalDir=(~mcAssetRoot~)/misc/legal/mcTrademarkPic=<img src="(~mcLegalDir~)trademark.jpg"alt="tm" />

</whmacros>

Listing 5: Text substitution macros can be defined in any WHTEKOfile.

You may have already realized that calling a macro is accomplished inW-HTML by putting its name inside parentils:(~mcLegalDir~)

Page SettingsInternally, WebHub has an object for each page in the application, aTwhPage component. Each page can carry some configuration detail, known as Page Settings. That is basically a TStringList that canbe used to write generic code.The following example (listing 6) shows how page settings can be usedto enter details which are later used to generate a Google sitemap file.(The Google sitemap feature is included as a standard module in Web-Hub. It works as-is for sites where every page has its own PageID. It requires modification for sites that use WebHub pages as templatesand need Google to a wide range of database-driven content.)

<whpage pageid="Login" desc="Customer Login"><whpagesettings>googlesitemap=include_all_lingvogooglechangefreq=monthlygooglepriority=0.7metarobot=index,nofollowmetadescription=Customers may login here.metakeywords=login; interactive; dynamic</whpagesettings>…</whpage>

<whpage pageid="HomePage" desc="Distribution"><whpagesettings>googlesitemap=include_all_lingvogooglechangefreq=monthlygooglepriority=1.0metarobot=index,followmetadescription=Full service east-coast distributionmetakeywords=courier service; trucking; </whpagesettings><whoutput>(~mcDocType2006~)<html><head><title>(~PageDesc~)</title>(~drHead~)

</head>…</whoutput>

</whpage>

<whdroplet name="drHead">(~HEADER|Content-Type: text/html;charset=utf-8~)(~waLingvo.execute~)<meta name="robots" content="(~pagesetting.metarobot~)" /><meta name="description"content="(~pagesetting.metadescription~)" />

<meta name="keywords" content="(~pagesetting.metakeywords~)" />

<link rel="stylesheet" type="text/css"href="/css/common.css" />

</whdroplet>

Listing 6: Page settings defined, then used to generate sitemap andshared header tags

Application ConfigurationYou may be wondering about custom settings needed for the appli-cation as a whole, such as a database name or the path to some utility used during processing. This is handled through the application-level configuration file. In that file, you can have settings which areagain basically a stringlist, although they are stored in XML format. Listing 7 shows a few sample settings and how they could be referenced in Delphi and in WebHub-HTML.

In XML:<AppSettings><AppSetting name="DemoGraphic" value="yes" /><AppSetting name="DBName" value="alias123" />

</AppSettings>

In PAS:ShowMessage(pWebApp.AppSetting['DemoGraphic']);ShowMessage(pWebApp.AppSetting['DBName']);

In WHTEKO:(~AppSetting.DemoGraphic~)(~AppSetting.DBName~)

Listing 7: Application settings in the config file; used in Delphi; usedin WHTEKO

Dozens of aspects of the application can be configured. Some peoplelike to use Notepad to edit the XML file directly. Beginners will find thatthe configuration utility, ZMAdmin.exe, is very convenient for exploringand changing settings. Figure 1 shows AppSettings as they look inZMAdmin.

Fig. 1: ZMAdmin provides the GUI for configuring the application;hints are often more detailed!

Live Content in DreamweaverIf the page layout expert on your team uses Dreamweaver, I highly

Page 16: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE16

DELPHI

recommend that you look through the user guide for the WebHub Ex-tension for Dreamweaver. That manual contains many screen shotsshowing exactly how it works. Remember, the big difference betweenWebHub's live content and that from ASP, PHP, etc., is that the Web-Hub content is generated specifically for Dreamweaver and provides100% of the HTML for each WebHub expression. Other plug-ins useapproximations for many of their dynamic pieces, especially for data-base content.If you are not a Dreamweaver fan, do not despair! People have built extreme sites using the WHTEKO editor provided with WebHub, oreven their favorite text editor.

Content ManagementStraight "out of the box," WebHub supports simplistic content ma-nagement. A WebHub site is easier to maintain than a static web sitebecause one usually shares all the headers and footers across thepages. However, if you want to use a database to store content, andmanage users and permissions, you need to build something for thatpurpose. One of the demos provides a simple example for doing so.One of our customers, www.netcat.com.au, has built a full-featuredCMS using WebHub. Another customer, www.webcentre.co.nz, builta CMS specifically for magazine and "news" content, and that is usedon the award-winning site, www.scitechdaily.com.

Web Apps that look like Delphi AppsDo you want your web application to look and act exactly like an exis-ting Delphi application? WebHub includes a fancy component nicknamed "F2H" meaning "form to html converter". This componentcan take any Delphi container, such as a form or a groupbox, and convert it to HTML. This content can be used as the basis for anypage, such that the surfer looks at something which looks like a Windows application.Whether this is desirable or not, depends on the target market andthe type of application.

You may know that IntraWeb specializes in this type of web applica-tion, and uses AJAX in creative ways to make web applications ope-rate like Delphi applications. There was an excellent presentation aboutthis at CodeRage 2008, and if you missed it, I recommend you find therecorded session. Look for "Rich User Interfaces with IntraWeb" byOlaf Monien at http://conferences.codegear.com/coderage08/sessi-ons.WebHub supports AJAX and includes three general-purpose commands to make AJAX features extremely easy to use. A Delphideveloper in Florida has used the WebHub AJAX commands to create a web version of his proprietary application. So if you want yourweb application to look and act like a Windows application, you certainly can.If you want **all** your web applications to look and act like your Delphi application, IntraWeb will be a better product for you than WebHub.

Apps with Skins; Re-useWould you agree that developers are most profitable when they canbuild something and then re-use it two or more times? WebHub developers often build an application with the idea of "skinning" it formultiple customers.This can be done in many ways. The simplest is to use an AppSettingto define the values that need to change for each customer, and use

a different configuration file for each customer.Whatever technique you use, the key is to use macros and droplets foreach piece of the design that will be swapped out. If you have anextra-talented CSS person on your team, you might not have to varymuch more than the path to the CSS file.If you want to skin your web app for two or more purposes, WebHubwill probably be a better product for you than IntraWeb.

Techniques inside DelphiThere are a few innovations inside Delphi which make WebHub applications unique and fun.

MultiTypeApp; TtpProjectMultiTypeApp is the name of a unit which, when included in your DPRinstead of Forms, makes your application compile easily as a normalWindows app, a Windows service, or as a console application. Because most WebHub developers eventually deploy their app as aWindows service, that is the default behavior. However by adding thePREVENTGUI compiler directive, you eliminate the as-service feature(and overhead).

TtpProject is the name of a component which we use to organize andsequence all the CreateForm statements relating to forms and data-modules, plus any initialization. When combining standard WebHubdatamodules and forms with custom units, an ordinary DPR can become quite messy, and often only the original developer under-stands the required sequence.TtpProject has a series of events which offer a place to put the nutsand bolts of project startup that would normally be in the DPR. It includes some features which are especially helpful to WebHub coders and can be ignored in other types of projects.

The use of TtpProject is always combined with the use of MultiType-App. Both are part of TPack and available with full source.

Let's look at one real-world example, keeping in mind two goals:1. Create objects in the correct order to avoid referencing something

which is still nil;2. Enable easy compilation of the app with zero GUI in case that is

needed later.

Fig. 2: Delphi Object Inspector with all the events on TtpProject (in Delphi 7)

Each event is called in the order shown. Thus all the datamodules arecreated FIRST (over 3 steps, as needed for WebHub); then any Initmethods are called on those datamodules in order to run code whichcannot run inside OnCreate due to interdependencies among modules; then the GUI is created; then the GUI is initialized.Listing 8 shows the code inside those events for an app in productionnamed CSShop, from the DMForCSShopPR.pas unit:

WebHub developers often build an application with the idea of "skinning"it for multiple customers

Page 17: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

magazine voor software development 17

DELPHI

procedure TDMforCSShopPM.ProjMgrDataModulesCreate1(Sender: TtpProject; var ErrorText: String;var Continue: Boolean);

beginCreateCoreWebHubDataModule; // includes TwhApplication

end;

procedure TDMforCSShopPM.ProjMgrDataModulesCreate2(Sender: TtpProject; const SuggestedAppID: String;var ErrorText: String; var Continue: Boolean);

beginif SuggestedAppID = '' thenbegin

ErrorText := 'Usage: csshop.exe /ID=shopname';Continue := False;Exit;

end;if AppIDToConfigFilespec(SuggestedAppID) = '' thenbegin

ErrorText := Format('WebHub Configuration Error in WHCentralInfo.xml%s' +'No configuration file for AppID "%s".',[sLineBreak, SuggestedAppID]);

Continue := False;Exit;

end;with pWebApp dobegin

AppID := SuggestedAppID;Refresh; // load all config and WHTEKO information

end;// provide notice to use while the rest is loadedCoverApp(SuggestedAppID, 2, 'reloading application',

False, ACoverPageFilespec);end;

procedure TDMforCSShopPM.ProjMgrDataModulesCreate3(Sender: TtpProject; var ErrorText: String;var Continue: Boolean);

begintry // uses MultiTypeApp, not Forms

Application.CreateForm(TdmCommon, dmCommon);Application.CreateForm(Tdmdb, db);Application.CreateForm(TdmFastTax, dmFastTax);Application.CreateForm(TdmAccount, dmAccount);Application.CreateForm(TdmCart, dmCart);Application.CreateForm(TdmVersionControl,

dmVersionControl);Application.CreateForm(TdmPlaceLookup, dmPlaceLookup);Application.CreateForm(TdmAS400, dmAS400);CreateStandardWHModules; // based on app configApplication.CreateForm(TdmwhNavigation, dmwhNavigation);Application.CreateForm(TDataModuleProductPhotos,

DataModuleProductPhotos);except

on E: Exception dobegin

ErrorText := E.Message;Continue := False;

end;end;

end;

procedure TDMforCSShopPM.ProjMgrDataModulesInit(Sender: TtpProject; var ErrorText: String;var Continue: Boolean);

begintry

db.Init;dmFastTax.Init;dmAccount.Init;dmCart.Init;dmVersionControl.Init;dmAS400.Init(dmCommon.cn1, dmCommon.tr1);InitCoreWebHubDataModule; // TwhApplicationInitStandardWHModules; // based on app-configdmwhNavigation.Init;DataModuleProductPhotos.Init;

excepton E: Exception dobegin

ErrorText := E.Message;Continue := False;end;

end;end;

procedure TDMforCSShopPM.ProjMgrGUICreate(Sender: TtpProject; const ShouldEnableGUI: Boolean;var ErrorText: String; var Continue: Boolean);

beginif ShouldEnableGUI thentryApplication.CreateForm(TfmWebHubMainForm,fmWebHubMainForm);

CreateStandardWHModulesGUI; // based on app-configApplication.CreateForm(TfmwhSponsor, fmwhSponsor);Application.CreateForm(TfmMemory, fmMemory);Application.CreateForm(TfmAS400, fmAS400);

excepton E: Exception dobeginErrorText := E.Message;Continue := False;

end;end;

end;

procedure TDMforCSShopPM.ProjMgrGUIInit(Sender: TtpProject;const ShouldEnableGUI: Boolean; var ErrorText: String;var Continue: Boolean);

beginif ShouldEnableGUI thentryInitCoreWebHubDataModuleGUI;InitStandardWHModulesGUI;fmwhSponsor.Init;Application.MainForm.Caption := pWebApp.AppID;UncoverApp(ACoverPageFilespec);WebMessage(''); // clear splash screen

excepton E: Exception dobeginErrorText := E.Message;Continue := False;

end;end;

end;

end.

Listing 8: Delphi code linked to the events shown in figure 2

To understand why all this is necessary, you need to think about howobjects are created and initialized. Getting the sequence correct isessential. For a WebHub application, you must instantiate a TwhApplication (OnDataModulesCreate1), set its AppID property andrefresh it (OnDataModulesCreate2), and then create other non-GUImodules which work once the TwhApplication is ready (OnData -ModulesCreate3). After all of those have been instantiated, we do another pass to call an Init procedure on any datamodule which needsto do something special. For example, it's usually better to connect toa database in the Init method, in case one needs to use any properties on other datamodules.

The GUI forms are created and initialized completely separately. Whilethe GUI is great during development and testing, it is often undesira-ble during production. By isolating the CreateForm statements forforms in OnCreateGUI, the whole project can quickly be compiled asa non-GUI edition when needed (by adding the PREVENTGUI directive).

It is possible to build WebHub apps without MultiTypeApp or TtpProject. However we recommend using them because the resulting code is more self-documenting.

Page 18: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE18

DELPHI

Too difficult? Talk to the Wizard!We built a few wizards to help you get your files started. They are accessible inside the Delphi IDE.1. New AppID - creates the XML and WHTEKO files needed for a

new application - do this first! Use the menu: Project > WebHub> New AppID

2. New Project - create the DPR and the unit containing TtpProject,with the events all coded for you. Use the menu: File > New >Other > Projects > WebHub Application and referencehttp://webhub.com/dynhelp:alias::newprojwizhowto for detailedsteps for creating your first hello-world app.

3. New Form – use this to add a module into an existing project.File > New > Form > WebHub Form

Modules aka PanelwareWhen Delphi first came out with form inheritance, TPack started leveraging inheritance to allow for user interfaces that would snap together in a way that was suitable for prototyping and testing. As WebHub applications on production servers usually prefer a mini-malist GUI, this made sense. At first, we called these snap-togetherforms "panelware". WebHub panels were often re-used in multiple projects. More recently, we have been talking about standard and custom "modules", where the GUI is optional.Let's illustrate this by reworking the banner idea we worked with earlier in listing 3. Of course, you would want that triggered from aweb page through a TwhWebAction component. In addition, for testing, you might want the feature triggered by a button click. Ideally, you would create two new units, a datamodule and a form.You would do this using the New Form Wizard. You would put thenon-visual functionality into the datamodule (i.e. the TwhWebAction),and you would put the visual button into the form. Now the form wouldbe a special form, descending from TutParentForm in TPack. This typeof form automatically adds itself as a "panel" into the WebHub GUI. Ifthat form is created first, it will be the first panel. If it is created third, itwill be the third panel.For advanced WebHubbers who want extra credit, it is possible to invent a keyword to associate with the new feature, say "banner". (Thisis worth doing if you intend to on-sell your module to other WebHubprogrammers.) You could then add a bit of code to your TtpProjectevents such that the core code in the datamodule and the GUI wouldbe brought in based on configuration entries in your application-levelconfig file.The custom configuration is shown in figure 3. Notice that the bannerfeature is "Enabled with GUI" by default, yet it is "Enabled" on a server which has been labeled as "production." The Delphi code whichmakes the feature come and go based on the configuration is shownin listing 9.

Fig. 3: ZMAdmin, used to vary the use of the banner feature for development vs production.

procedure TDMSampleForWHProject.ProjMgrDataModulesCreate3(Sender: TtpProject; var ErrorText: String;var Continue: Boolean);

beginCreateStandardWHModules;if (pWebApp.Startup.CustomModuleStatus('banner') <>mstatusDisabled) thenApplication.CreateForm(TDM001, DM001);

{ Special Comment for DataModules - do not delete!

This comment is used by the WebHub Wizard to positionnon-gui CreateForm statements for you, just above here.You may add your own CreateForm statements as well,either above or below this comment, as you wish. }

end;

procedure TDMSampleForWHProject.ProjMgrDataModulesInit(Sender: TtpProject; var ErrorText: String;var Continue: Boolean);

beginInitCoreWebHubDataModule;InitStandardWHModules;if (pWebApp.Startup.CustomModuleStatus('banner') <>mstatusDisabled) thenDM001.Init;

end;

procedure TDMSampleForWHProject.ProjMgrGUICreate(Sender: TtpProject; const ShouldEnableGUI: Boolean;var ErrorText: String; var Continue: Boolean);

begin{$IFNDEF PREVENTGUI}if ShouldEnableGUI thenbeginApplication.CreateForm(TfmWebHubMainForm,fmWebHubMainForm);

CreateStandardWHModulesGUI;

if pWebApp.Startup.CustomModuleStatus('banner') =mstatusEnabledWithGUI thenApplication.CreateForm(TfmAppPanel, fmAppPanel);

{ Special Comment for Forms - do not delete!

This comment is used by the WebHub Wizard}end;

{$ENDIF}end;

Listing 9: Creating modules based on status in application-levelconfig file

When you are in a rush, you probably would not take the time to separate the GUI, give the feature a name, and load it conditionallybased on configuration entries. However, if you wanted to develop amodule to sell to other WebHub developers, or if you wanted to compile one large application for multiple purposes and needed to beable to turn major features on and off for various customers, you mighttake advantage of this approach.

SOAPAny WebHub application can surface some or all of its features via thestandard SOAP interface, and we definitely recommend this. Precisely, any TwhWebAction derivative can be SOAP enabled by toggling the SOAPCallOk property from False to True.This is demonstrated in the "spam aversion" demo, http://demos.href.com/htun. If you click into that demo, you can see how SOAP documentation is generated automatically, both human-readable and

Any WebHub application can surfacesome or all of its features via the standard SOAP interface

Page 19: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

magazine voor software development 19

DELPHI

everything needed for software interfacing. In that demo, use the[Source] link to see all the Delphi code, especially the whStop-Spam_fmWh.pas file which shows how to add a custom method within and out parameters.

Customer CommentsI thought you might like to hear from "ordinary" Delphi programmershave to say about WebHub. The following two comments are frompeople who have built significant ventures using WebHub and Delphi.The first operates in Germany and the second in the USA.

“We have been working with WebHub since March 2000. At that time,we intensively evaluated web development options: Java, PHP, ASP,diverse frameworks in each of these languages. Even at that time,none of these evaluated tools impressed us with their performance.Also, the cost effectiveness and usability was often unbelievably lac-king. Whoever has even once labored with Java and Struts and theirXML will understand exactly what I am talking about. After months ofsearching and evaluating, I found href.com.It was like a miracle. We could finally develop our real estate portal inDelphi, logically and consistently. It was wonderful.The performance, the stability, the ease of use, the simplicity -- all thiswas, and still is today, the basis for us to say that the WebHub framework is the number 1 choice for anyone who wants to developa stable, high-traffic, modular, high-performance web application.We know Java, we know PHP, we know Ruby and Ruby on Rails. Yet,if we were to build our real estate portal again, starting today, we woulddo it with 100%-awareness with the friendly WebHub.If it were possible to give 5 stars to WebHub, we would give it 6 stars.At this point, many, many thanks to Ann, for the always-friendly, highquality technical support, the quick clarification of ideas and quite simply for the best web tool which I use daily.”-- Andreas Orth, www.my-next-home.de, customer from 2000 to2009

“We have had several iterations of migrating to ASP.Net and all havefailed in matching or even approaching the performance and the productivity of Delphi + WebHub. All of these attempts have been byprofessional ASP.Net developers.Our competition (using ASP.Net, ASP, PHP, Java) have not been ableto approach the complexities, performance, etc., we have attained onour site -- regardless of the number of developers they commit.”-- John Correa, www.res.net, customer from 1997 to 2009

Licensing and Source Code AvailabilityWe have a fine-grained way of providing source code. We recommendthat you start with a free evaluation license (www.href.com/trywhub)and make sure that you are in love with WebHub. The latest pricesare always available at http://www.href.com/hrefshop.WebHub is available for Delphi 6 and above; Delphi 2009 is recom-mended. TNativeXml, ZaphosdMap and most of TPack also compilein Kylix 3 and Delphi for Dot Net through D2007. TNativeXml additio-nally compiles under FreePascal.

ConclusionIn these articles, I've walked you through the facets of WebHub whichcontribute to its unique level of power and flexibility. I invite you to usethis knowledge -- in Delphi, with WebHub -- or otherwise.

Who should build apps with WebHub? Ideally, WebHub is for pro-grammers who love expressing themselves in Object Pascal, who areinterested in skinning their web application for multiple audiences, whoneed to translate their site content into two or more lingvos, who seeadvantages in partnering with a web artist, and who want to build so-mething long-lasting.

I have been very quiet about WebHub since 2002; we were consumedwith extensive refactoring. We are now officially open again for newcustomers, and I look forward to hearing from readers with questionsor comments. Reach me through our site, http://www.href.com/contact. •

Fig. 4:. Once more where we started off at the cables suspendingthe Brooklyn Bridge, April 2004.

Ann Lynnworth

Ann Lynnworth was born near Boston, Massachusetts USA at theright time to catch the informationtechnology wave. In 1978, shefound she could not resist learningto program fancy macros for Word-Perfect, and she has never been af-raid to pick up a manual and/orguess her way into a new techno-logy. She started her "Software

Doctor" consulting business in 1983 on Apple's early computers,published WordStar at Your Fingertips, wrote Situation Analyst forthe IBM PC, helped create Ronstadt's Financials and then joinedXL/Proteus to learn all about Paradox and a bit about SQL. Skip-ping ahead to 1994, Ann learned Delphi and soon co-foundedHREF Tools and has worn many hats with the internet tools com-pany, the most enjoyable of which was producing “Tech TalkRadio” for several years for WebHub customers. A dynamic spea-ker with an unusual point of view, Ann has had rave reviews fromattendees in training seminars and at technical conferences. Annholds an associate art's degree from Simon's Rock College anda bachelor’s degree in psychology from Wellesley College, also inMassachusetts.

Page 20: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

Advertentie VNU

Page 21: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

UX Koen Zwikstra

Op codeplex.com, een Open Source Project community, zijn inmiddelseen kleine 600(!) Open Source projecten te vinden die gerelateerd zijnaan Silverlight. Dit artikel biedt bij lange na geen volledig overzicht,maar geeft een korte beschrijving van een tiental populaire OpenSource projecten. De geselecteerde projecten zijn opgedeeld in decategorieën Controls, Design Patterns, Graphics Engines en Runtimeextensies.

ControlsDe Silverlight runtime bevat een verzameling controls als een button,combo, list, tab, enz. Naast deze basisverzameling zijn er in verschil-lende Open Source projecten andere controls beschikbaar, variërendin functionaliteit van eenvoudig tot zeer complex.

Fig. 1: DeepEarth control

Deep Earthhttp://deepearth.codeplex.comWanneer je een interactieve kaart van de wereld op wilt nemen in je applicatie, is het zeker de moeite waard om te kijken naar Deep Earth.Dit project maakt gebruikt van Deep Zoom en Virtual Earth om eenmap control op te bouwen, vergelijkbaar met Google Maps. De con-trol is volledig aan te passen, en biedt mogelijkheden voor het toevoegen van eigen navigatie controls en layers waarop de ontwikkelaar zelf visuele elementen kan tekenen.

Microsoft Silverlight Toolkithttp://silverlight.codeplex.comDe Microsoft Silverlight Toolkit is zonder twijfel het meest bekende Silverlight Open Source project. Het project wordt beheerd door eenteam van Microsoft ontwikkelaars en bevat een uitgebreide verzame-ling controls en professionele UI themes. De controls bestaan onderandere uit een AutoCompleteBox, DockPanel, TreeView, ViewBox enCharting controls. De populaire controls die uitontwikkeld zijn, wordenuiteindelijk opgenomen in de Silverlight runtime.

De Silverlight Toolkit is een must-have;naast de Silverlight SDK is elke Silverlightdeveloper min of meer verplicht om ook deToolkit te gebruiken.

Silverlight Extensionshttp://slextensions.codeplex.comSilverlight Extensions is een zeer uitgebreidOpen Source project en bevat vele controlsen andere hulpmiddelen. Silverlight Contrib,een vergelijkbaar project, is recentelijk sa-mengevoegd met Silverlight Extensions enhet resultaat is een API met honderdenbruikbare classes. Het project bestaatonder andere uit een color picker, menu,virtueel stack panel, zip functionaliteit, dynamic imaging en tekst parsers. Naastde controls biedt het project ook design-time hulpmiddelen als ReSharper templa-tes en Visual Studio code snippets.Silverlight Extensions wordt onderhoudendoor een aantal prominente developers inde Silverlight community.

magazine voor software development 21

Silverlight en Open SourceSilverlight is een relatief jong platform voor het ontwikkelen van zogenaamde Rich Internet Applicaties op basis van .NET. De komst van een nieuw applicatieplatform is veelal het beginvan de opkomst van Open Source projecten en Silverlight is hier geen uitzondering op. Er zijninmiddels een aantal waardevolle Open Source projecten voor Silverlight beschikbaar. In dit artikel wordt een overzicht geschetst van deze projecten en worden er suggesties gedaan voorhet zelf opzetten en beheren van een Open Source project.

Op codeplex.com zijn inmiddels eenkleine 600(!) Open Source projecten te vinden die gerelateerd zijn aan Silverlight

De Silverlight Toolkit is een must-have

Page 22: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE22

Fig. 2: Slide.Show 2

Silverlight Video Playerhttp://sl2videoplayer.codeplex.comBen je op zoek naar een kant en klare video speler voor Silverlight,dan is de Silverlight Video player zeer waarschijnlijk een goede kandidaat. De Player is een relatief eenvoudige user control die naareigen inzichten visueel aangepast kan worden met behulp van stylesen templates.

Slide.Show 2http://slideshow2.codeplex.comSlide.Show 2 is een control voor het publiceren van foto- en video-presentaties. De oorspronkelijke versie was ontwikkeld voor Silverlight

1.0 maar deze is nu volledig herschreven voor Silverlight 2. Slide.Show2 is volledig configureerbaar en biedt standaard ondersteuning voorXML-data en de fotosite Flickr. De control is uit te breiden met zelf ontwikkelde foto- en video-providers.Slide.Show 2 is een Open Source project van Vertigo, een bedrijf meteen goede reputatie op het gebied van WPF- en Silverlight-applicaties.

Design PatternsWanneer je een serieuze applicatie ontwik-kelt is het goed om bij het ontwerp en deontwikkeling van de applicatie gebruik temaken van beproefde design patterns. Eendesign pattern biedt een oplossing vooreen veel voorkomend probleem wat, mitsgoed toegepast, de onderhoudbaarheidvan de applicatie ten goede komt. Verschil-lende Open Source projecten definiëren de-sign patterns die specifiek voor Silverlightbedoeld zijn.

Prismhttp://compositewpf.codeplex.comPrism (ook wel Composite Application Gui-dance genoemd) is oorspronkelijk ontwik-keld voor WPF, en biedt nu ookhulpmiddelen voor het ontwikkelen van Sil-verlight-applicaties. Prism komt uit de hoekvan Microsoft patterns & practices, waarbeproefde praktijkoplossingen worden aan-geboden voor de verschillende aspectenbinnen software ontwikkeling. Prism richtzich op de ontwikkeling van modulaire applicaties.

In het project worden onder andere de Command, Adapter en Facadedesign patterns toegepast. Prism is een project wat zeer bruikbaarkan zijn voor het ontwerp en de ontwikkeling van grote en complexebusiness applicaties. Het Prism Open Source project bestaat uit eenreferentie implementatie, een library en uitgebreide documentatie.

Silverlight.FXhttp://projects.nikhilk.net/SilverlightFXEen project wat zeker niet onvermeld mag blijven is Silverlight.FX vanNikhil Kothari. Nikhil is een software architect in de Microsoft Develo-per Divisie en is onder andere bekend van zijn Script# project (een C#compiler die JavaScript genereert). Silverlight.FX is een applicatiefra-mework voor het ontwikkelen van Rich Internet Applicaties met Sil-verlight. Het framework voorziet in een applicatiemodel, UIcomponenten, declaratieve views en UI effects. Silverlight.FX past verschillende bekende design patterns toe alsModel-View-ViewModel, MVC, IoC containers, enz.

Graphics EnginesOp grafisch gebied zijn de mogelijkheden van Rich Internet Applicatieplatformen, zoals Silverlight, superieur aan HTML. Met Silverlight kun-nen complexe grafische 2D en 3D applicaties ontwikkeld worden. Voorde ontwikkeling van deze applicaties wordt vaak gebruik gemaakt vanzogenaamde grafische engines. Een grafische engine biedt de ont-wikkelaar via een model een hulpmiddel voor het tekenen van entitei-ten. In de Silverlight Open Source wereld is een aantal grafischeengines beschikbaar.

Farseer Physics Enginehttp://farseerphysics.codeplex.comDe Farseer Physics Engine is een eenvoudig te gebruiken 2D physicsengine. Een physics engine zorgt ervoor dat objecten in een virtuelewereld zich realistisch gedragen. De engine berekent welke krachten,zoals bijvoorbeeld de zwaartekracht, een object beïnvloeden en beweegt het object overeenkomstig deze krachten. Een physics engine berekent ook of objecten met elkaar in botsing komen (objectcollision) en biedt de ontwikkelaar de mogelijkheid om daar op in tehaken. De Farseer Physics engine is de meest uitgebreide OpenSource physics engine die nu beschikbaar is voor Silverlight.

Fig. 3: Kit3D in actie

UX

Page 23: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

Noteren in agenda:

19 & 20 oktober a.s.SDN Conference

magazine voor software development 23

De engine is oorspronkelijk ontworpen voor het XNA platform (XBOX360 en Windows) maar is herschreven voor Silverlight.

Kit3Dhttp://kit3d.codeplex.comKit3D is een 3D grafische engine met een API die overeenkomt met de3D API van Windows Presentation Foundation, zoals deze in de System.Windows.Media.Media3D namespace is gedefinieerd. Kit3Dis nog niet productierijp, maar biedt een goede indruk van wat de mo-gelijkheden zijn voor het ontwikkelen van 3D applicaties. Met Kit3Dkunnen meer geavanceerde 3D applicaties ontwikkeld worden danmogelijk is met de beperkte perspective 3D transformaties van Silverlight 3.

Runtime extensiesMicrosoft neemt Open Source serieus en dat is goed te merken aande hoeveelheid grote Open Source projecten voor Silverlight die afkomstig zijn van Microsoft zelf. Silverlight Toolkit en Prism zijn daarmooie voorbeelden van, maar Microsoft gaat nog veel verder door eenaantal runtime extensies als Open Source ter beschikking te stellen.

Silverlight Dynamic Languages SDKhttp://sdlsdk.codeplex.comMet behulp van de Silverlight Dynamic Languages SDK kunnen Silverlight applicaties ontwikkeld worden met dynamische program-meertalen als Ruby en Python. Een dynamische programmeertaal kenmerkt zich door de mogelijkheid om tijdens het draaien aanpas-singen aan het programma te doen. Variabelen hoeven niet gedecla-reerd te worden en code en objecten kunnen runtime wordenaangepast. Bij de huidige versies van statische talen als C# en VB.NETis dit onmogelijk of niet eenvoudig te doen. Dynamische talen staan tegenwoordig steeds meer in de belangstelling.De SDK implementeert een koppeling tussen Silverlight en de Dyna-mic Language Runtime (DLR). De DLR is ook volledig Open Source.

Hebrew & Arabic Language supporthttp://silverlightrtl.codeplex.comDe Silverlight runtime biedt geen ondersteuning voor talen die vanrechts naar links (RTL) geörienteerd zijn. Wil je deze taalondersteuningtoch in je applicatie aanbieden, dan kun je gebruik maken van dit OpenSource project. Het project bevat een verzameling controls en helperfuncties voor het correct tekenen van tekst die zowel links-naar-rechts(LTR) als de rechts-naar-links (RTL) georiënteerd is.

Open Source software ontwikkelenHet is vrij eenvoudig om zelf een Open Source project te starten en tebeheren. Er bestaat een aantal gerenommeerde sites die Open Sourceprojecten hosten, zoals sourceforge.net en codeplex.com. Deze OpenSource sites bieden een uitgebreid scala aan beheerfuncties. Zakenals source control, versiebeheer, discussieforum, wiki en statistiekenzijn in de meeste gevallen uitstekend geregeld.Kijk goed om je heen voor je een Open Source project start. Wellichtkun je participeren in een bestaand project. Neem daartoe contact opmet het betreffende projectteam en in de meeste gevallen zul je eenzekere reputatie opgebouwd moeten hebben, wil je worden toegelaten.

Open Source sites bieden een uitgebreid scala aan beheerfuncties

Koen Zwikstra

Koen Zwikstra is een ervaren Silver-light ontwikkelaar van het eerste uur.Met zijn onderneming richt hij zichvolledig op de Silverlight technolo-gie en verzorgt hij Silverlight consultancy diensten aan zijn opdracht gevers. Daarnaast is hijverantwoordelijk voor de ontwikke-ling van verschillende producten,

waaronder Silverlight Spy, en levert hij een actieve bijdrage aan dewereldwijde Silverlight developer community.

UX

LicentieHet bespreken van de voors en tegens van de verschillende OpenSource licenties valt buiten de scoop van dit artikel. Het is wel verstandig om goed na te denken over de licentie waaronder je desource code wilt vrijgeven. Met de licentie geef je aan wat een ontwikkelaar wel en niet met de source code mag doen. Een aantal licenties leggen soms verregaande restricties op aan de applicatie diewordt ontwikkeld met behulp van het Open Source project. Zo kanhet zijn dat een Open Source licentie de ontwikkelaar dwingt om zijneigen applicatie ook als Open Source te distribueren.Het opstellen van een eigen licentie is meestal niet nodig, Open Sourcehosting sites bieden een ruime keuze uit een aantal standaard licenties die in de meeste gevallen voldoen.

ConclusieEr is inmiddels een groot aantal waardevolle en bruikbare Open Sourceprojecten voor Silverlight beschikbaar. Ervaren en enthousiaste ontwikkelaars uit de Silverlight community en van Microsoft makenzich sterk voor de ontwikkeling van kwalitatief hoogwaardige OpenSource projecten. Wanneer je een applicatie in Silverlight wilt bouwen,is het verstandig om op de hoogte te zijn van wat er in de Open Sourcewereld te koop is. Het is immers goed mogelijk dat de functionaliteitdie je wilt ontwikkelen al beschikbaar is. In dit artikel zijn slechts eenbeperkt aantal projecten besproken, er bestaan vele honderden OpenSource projecten die gerelateerd zijn aan Silverlight. De hoeveelheidprojecten is een indicatie dat de Silverlight Open Source communitygroeit en bloeit.Wanneer je zelf een Open Source project wilt opstarten, bieden sitesals codeplex.com uitstekende hulpmiddelen om je project succesvolte beheren. •

Microsoft neemt Open Source serieus

Page 24: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

DATABASES André van ’t Hoog en Arjan Pot

HierarchieEen hiërarchische structuur noemen we ook vaak een boomstructuur.Klassieke voorbeelden zijn werknemers onder leiding van andere werk-nemers, een stamboom, een bestandsysteem, postings in een forum,gebruikers van computers. Gegevens in XML zijn per definitie hiërarchisch. In dit artikel gebruiken we een organisatiestructuur alsvoorbeeld.Om hiërarchische gegevens in een relationele database op te slaanwordt vaak gebruik gemaakt van recursie: één kolom in de tabel wijstnaar de primary key van dezelfde tabel (zie figuur 1).

Fig. 1: Klassiek datamodel

Deze structuur is simpel en doeltreffend en staat ook wel bekend als“adjacency list model”. Wanneer je er mee gaat werken, wordt snelduidelijk dat een relationele database weinig ondersteuning biedt voorhiërarchische gegevens. In SQL Server 2000 moest je aan de slag metCURSORS en tijdelijke tabellen. Sinds SQL Server 2005 kun je gebruik maken van Common Table Expressions. Met SQL Server 2008 is er een nieuw datatype dat we kunnen gebruiken: HierarchyID. Het datamodel dat we in ons voorbeeld ge-bruiken staat in figuur 2. De kolom “Node” is van het type HierarchyID.

Fig. 2: Datamodel met HierarchyID

Het datatype HierarchyID bevat een path naar een item; dit wordt opgeslagen in een varbinary veld. Het path is als string makkelijk telezen. Tussen slashes “/” staan nummers die de parents van het itemvoorstellen. Zie b.v. de structuur in figuur 3.

Fig. 3: Voorbeeldhiërarchie

User-defined typeHierarchyID is geimplementeerd als een CLR user-defined type (UDT).Dit betekent dat er net zoals in C# methodes zijn aan te roepen. Hieronder volgt een samenvatting van de methodes. Let op dat allescase-sensitive is. De voorbeelden zijn gebaseerd op de tabel in figuur2 en de boomstructuur in figuur 3.

Proven technologyHierarchyID maakt intern gebruik van het .NET type OrdPath. Dittype is in SQL Server 2005 geintroduceerd om het XML type teondersteunen. XML wordt in SQL Server “platgeslagen” en geor-dend met OrdPath. Het HierarchyID type is daarmee gebaseerdop bewezen technologie. Wil je precies weten hoe HierarchyIDwerkt, dan is het zeker de moeite waard om eens te zoeken opOrdPath.HierarchyID is onderdeel van System.Data.SqlTypes, waardoor jehet kunt gebruiken buiten SQL Server, gewoon in een C# of VisualBasic project.

HierarchyID in

SQL Server 2008Relationele databases zoals SQL Server zijn sterk in het opslaan van relationele gegevens. Sommige gegevens zijn echter beter te ordenen in een hiërarchisch model, b.v. de structuur vaneen organisatie. SQL Server 2008 introduceert een nieuw datatype voor hiërarchische gegevens:HierarchyID. HierarchyID is een eenvoudig datatype met slechts 8 relevante functies, maar wijktaf van de manier van werken die we gewend zijn in SQL Server. In dit artikel leggen we het concept uit en laten we zien hoe je HierarchyID kunt gebruiken.

MAGAZINE24

Page 25: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

DATABASES

ToString()Vertaalt de inhoud van het varbinary veld naar een leesbaar path. Zielisting 1.

SELECTNode, Node.ToString() AS NodePath

FROMOrganization

Node NodePath------------ ------------0x /0x58 /1/0x5AC0 /1/1/0x5B40 /1/2/0x68 /2/0x6A241BE8EC /2/-1.5.-123/

Listing 1

De ToString method gebruik je om het path te zien of om gegevensover te zetten naar een extern system.

Parse(path)Vertaalt een leesbaar path naar een HierarchyID. Dit is de omgekeerdebewerking van ToString(). Dit is een static method. Zie listing 2.

SELECThierarchyid::Parse('/5/4/3/2/1/') AS Node

Node ------------ 0x8E17B560

Listing 2

Parse gebruik je om gegevens met een editor in te voeren, b.v. vanuitSQL Server Management Studio, of om gegevens te importeren van-uit een ander systeem. Als je een ongeldig path opgeeft, krijg je een.NET exception. Overigens wordt de Parse method impliciet uitgevoerd zodra je een string toekent aan een veld van het type hierarchyid.

GetRoot()Levert de root node; in de huidige implementatie van HierarchyID is dataltijd “/”. Dit is een static method. Zie listing 3.

SELECThierarchyid::GetRoot() AS Node,hierarchyid::GetRoot().ToString() AS NodePath

Node NodePath------------ ------------0x /

Listing 3

GetLevel()Levert het nivo van de node in de hierarchy. De root heeft level 0. Zie

listing 4.

SELECTNode.ToString() AS NodePath, Node.GetLevel() AS Level

FROMOrganization

NodePath Level-------------- --------------/ 0/1/ 1/1/1/ 2/1/2/ 2/2/ 1/2/-1.5.-123/ 2

Listing 4

In het voorbeeld van een organisatie kun je hiermee alle suborganisa-ties op een bepaald nivo ophalen.

GetAncestor(n)Levert de parent van de node, die n niveaus hoger staat. Zie listing 5.Vraag je naar een nivo dat niet bestaat, dan wordt er NULL geretourneerd.

SELECTNode.ToString() AS NodePath,Node.GetAncestor(1).ToString() AS ParentPath, Node.GetAncestor(2).ToString() AS ParentsParentPath

FROMOrganization

NodePath ParentPath ParentsParentPath-------------- --------------- ------------------/ NULL NULL/1/ / NULL/1/1/ /1/ //1/2/ /1/ //2/ / NULL/2/-1.5.-123/ /2/ /

Listing 5

In het voorbeeld van een organisatie kun je hiermee makkelijk vragenonder welk punt van de organisatie je zit.

IsDescendantOf(parent)Levert “1” op als de node valt onder parent, anders “0”. Opvallend isdat IsDescendant() ook zichzelf oplevert. Ook alle subnodes voldoenaan IsDescendantOf().Deze methode is zeer geschikt om records te selecteren in de WHEREclause. Listing 6 is een voorbeeld van het ophalen van alle child records van item /2/.

SELECTNode.ToString() AS Descendant_Of_2

FROMOrganization

WHERENode.IsDescendantOf('/2/') = 1

Descendant_Of_2-------------------/2//2/-1.5.-123/

Listing 6

In het voorbeeld van een organisatie kun je hiermee suborganisatiesophalen. De drie methodes GetLevel(), GetAncestor() en IsDescendantOf() gebruik je om records te selecteren. In combinatie met SQL is het aantal mogelijke queries eindeloos.

GetDescendant(child1, child2)Als je denkt dat je hiermee de records kunt opvragen die liggen onderde huidige node, dan heb je het mis. Zoals alle methods van HierarchyID is er geen kennis van de tabellen of de kolommen. AlleHierarchyID methods zijn static of ze voeren een berekening uit op dehuidige node, verder niks. De GetDescendant method levert een “mogelijk” child onder de huidige node. De parameters chlid1 en child2 worden gebruikt om depositie te beperken, beide mogen null zijn. Je kunt dit bijvoorbeeld gebruiken wanneer je een nieuwe node toevoegt. Zie listing 7.

SELECTNode.ToString() AS NodePath, Node.GetDescendant(NULL,NULL).ToString()AS DescendantPath

FROM

magazine voor software development 25

Page 26: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

DATABASES

Organization

NodePath DescendantPath----------------- ----------------- / /1//1/ /1/1//1/1/ /1/1/1//1/2/ /1/2/1//2/ /2/1//2/-1.5.-123/ /2/-1.5.-123/1/

Listing 7

In listing 8 zie je wat het resultaat is, als je vraagt naar een node onder/ en tussen /1/ en /2/.

SELECT hierarchyid::Parse('/').GetDescendant('/1/','/2/')

.ToString() AS NodePath

NodePath ------------/1.1/

Listing 8

De parameters child1 en child2 worden gevalideerd binnen de contextvan de node. Dit kan resulteren in .NET exceptions.In het voorbeeld van een organisatie gebruik je deze method als je deorganisatie gaat uitbreiden.

VolgordeNaast de hiërarchie leg je met HierarchyID ook de volgorde vannodes vast. Dit in tegenstelling tot het adjacency list model. In fi-guur 3 zie je bijvoorbeeld dat B links van C ligt en dat D links vanE ligt.

GetReparentedValue(oldparent, newparent)Bij het verplaatsen van records moet je zelf alle onderliggende recordsverplaatsen. Dat kan best lastig zijn. Je moet er bijvoorbeeld rekeningmee houden dat alle node’s een uniek path hebben. De method GetReparentedValue biedt hulp.

SELECTNode.ToString() AS NodePath, Node.GetReparentedValue('/1/','/2/').ToString()

AS NewNodePathFROMOrganization

WHERENode.IsDescendantOf('/1/') = 1

NodePath NewNodePath-------------- -------------- /1/ /2//1/1/ /2/1//1/2/ /2/2/

Listing 9

In listing 9 wordt een nieuw path bepaald voor alle nodes onder /1/ bijhet verplaatsen naar /2/. De node /1/1/ wordt dan /2/1/. Zoals je zietwordt er geen rekening mee gehouden dat er al een node bestaat metpath /2/1/. Het is puur een berekening die uitgevoerd wordt, zonderte kijken naar de data die aanwezig is in de tabel. Er wordt zelfs geenupdate op het record uitgevoerd. Verderop laten we zien hoe je dat zelfin SQL kunt schrijven.De parameter oldparent wordt gevalideerd binnen de context van denode. Dit kan resulteren in .NET exceptions.In het voorbeeld van een organisatie gebruik je deze methode als je deorganisatie anders gaat indelen.

LimietenEen path mag maximaal 256 bytes lang zijn. Het aantal mogelijkenodes is daarmee voldoende gewaarborgd. De enige limiet diemisschien ooit bereikt wordt, is de lengte van een path. Wanneernodes vaak verplaatst worden, zal het path snel langer worden.Een klein experiment laat zien dat er circa 160 nivo’s mogelijk zijnbij nodes van 10 cijfers. Wanneer een node uit 50 cijfers bestaat zijn33 nivo’s mogelijk. Geen reden tot ongerustheid. En mocht degrens bereikt zijn, dan kun je altijd nodes voorzien van nieuwe ge-tallen zonder de hiërarchie aan te tasten.

Database ontwerpBij het ontwerpen van een database is het verstandig rekening te houden met de eigenschappen van HierarchyID. Het zal inmiddels duidelijk zijn dat HierarchyID geen kennis heeft vande context waarin het gebruikt wordt. De programmeur of database-beheerder zal zelf nog het nodige werk moeten verrichten.

Hiërarchie brekenHet is erg eenvoudig om een hiërarchie te breken; je kunt er gewooneen node tussenuit halen. Bij het aanpassen van je hiërarchie moet jezelf alle onderliggende nodes bijwerken en conflicten voorkomen. In listing 10 staat een voorbeeld van een update statement waarmee jedat zou kunnen doen.

UPDATEOrganization

SETNode = Node.GetReparentedValue('/1/', '/2/')

FROMOrganization

WHERENode.IsDescendantOf('/1/') = 1

Listing 10

ConstraintsDatabase-inconsistentie kan worden voorkomen door een unique con-straint te plaatsen op de HierarchyID kolom. Een foreign key constraintop een computed column van de parent en de kolom zelf kan de re-ferentiële integriteit borgen. Het is geen goed idee om de primary keyvan een tabel op de HierarchyID kolom te zetten, de nodes kunnen im-mers wijzigen waardoor relaties met andere tabellen zullen breken.

Stored proceduresHet gebruik van stored procedures is aan te bevelen om records toete voegen, te verplaatsen en te verwijderen.

LINQ, Entity Framework en ADO.NETDe LINQ to SQL designer van Visual Studio 2008 loopt vast opHierarchyID. Het Entity Framework doet het een stuk beter: het negeert de kolom met HierarchyID maar loopt gelukkig niet vast.ADO.NET doet het uitstekend; de DataReader herkent HierarchyID.De DataSet wordt goed ondersteund, de HierarchyID kolom wordtgetoond als string en bij een update wordt de string geparsedzodat je de inhoud van de HierarchyID kolom kunt wijzigen.

SamenvattingHierarchyID is een nieuw data type in SQL Server 2008. HierarchyIDreikt een nieuwe manier aan om gegevens op te slaan in een database. Het principe is betrekkelijk simpel en efficiënt. Voor programmeurs en databasebeheerders zal het even wennen zijn omHierarchyID te begrijpen en toe te passen. Ook de database-ontwer-per doet er verstandig aan om zich in de techniek te verdiepen. Metname de combinatie van .NET methods en SQL vergt gewenning.

MAGAZINE26

Page 27: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

DATABASES

Links• http://msdn.microsoft.com/en-us/library/bb677173.aspx• http://wiki.evident.nl/HierarchyID+-+Design+considerations.ashx• http://wiki.evident.nl/HierarchyID+-+Introduction.ashx •

André van ’t Hoog

André van ’t Hoog is senior softwareontwikkelaar bij Evident InteractiveB.V. Hij is nu ongeveer 20 jaar werk-zaam in de ICT-sector en heeft zichsinds 1996 gespecialiseerd in Microsoft technologie, met name.NET en SQL Server. Recent is hijmet name bezig geweest met deontwikkeling van internet applicaties

waarbij onder andere gebruik is gemaakt van (eerst) MCMS 2002en (later) Sharepoint 2007. Daarnaast is hij momenteel in deeltijdactief als database administrator voor een aantal op SQL Servergebaseerde applicaties.

Arjan Pot

Arjan Pot is een door Microsoft gecertificeerde senior software ontwikkelaar bij Evident InteractiveB.V. Hij specialiseert zich in Web Development, zowel back-end alsfront-end. Van assembly program-meren op Micro controllers tot con-figureerbare workflow heeft Arjanzich ontwikkeld tot allround

programmeur. Speerpunten in zijn kennis zijn C#, SQL Server enASP.NET. Hij ontwikkelt bij voorkeur iteratief en in een hecht multidisciplinair team.

UX TIP: 50 beautiful Flash websites

Met de komst van Silverlight en Flash is het voor designers en developers mogelijk een nieuwe generatie websites te maken. Animatie en interactiviteit dragen bij aan een indrukwekkende visuele experience. Smashing magazine verzamelde 50 mooie Flash websites om inspiratie op te doen: http://www.smashingmagazine.com/2009/06/07/50-beautiful-flash-websites/.

Advertentie Barnsten/Embarcadero

Page 28: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

Advertentie Bergler

Page 29: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

CORESYSTEMS Norbert Mimpen

FloraHolland had diverse bedrijfskritischeCobol-maatwerksystemen op een oude infra-structuur (VAX/VMS) draaien ter ondersteuningvan haar logistieke en financiële processen,waaronder de facturatie. De continuïteit van deIT-ondersteuning van deze processen dreigdeernstig in gevaar te komen door een oplopendeschaarste aan Cobol-expertise binnen de eigenorganisatie.Hiernaast was FloraHolland zich ook bewustvan het feit dat de operationele kosten van hunoude infrastructuur factoren hoger lagen dandie van een moderne infrastructuur, zoals

Windows. Ook was het voor FloraHolland duidelijk dat de productivi-teit van het onderhoud op hun Cobol-systemen door migratie naareen nieuwe technologie kon worden verbeterd.Migratie naar een moderne technologie was voor FloraHolland danook een logische keuze. Ook de keuze van de doeltechnologie kostteFloraHolland geen moeite. De standaard architectuur binnen Flora-Holland is geënt op Microsoft C#. Deze expertise heeft FloraHollandal ruimschoots beschikbaar. FloraHolland koos in eerste instantie ervoor om zijn Cobol-systemen zelf te converteren naar C#, en welhandmatig. In deze conversie zou meteen de platformmigratie van deoude infrastructuur naar Windows worden meegenomen.

UitdagingenVanwege grote technische verschillen tussen Cobol en C# verliep dehandmatige conversie door FloraHolland moeizaam. Statements van

de bron- en doeltaal leken op het eerste gezicht dezelfde werking tehebben, maar bleken uiteindelijk heel verschillend te zijn.Een concreet voorbeeld hiervan is de toekenning van waarden. In bepaalde gevallen zal Cobol de toegekende waarde afkappen, terwijldat in C# niet gebeurt, waardoor een verschillende functionele werkingvan de programma’s optreedt. Zonder diepgaande kennis van zowelbron- als doeltaal kunnen statements dus onjuist worden vertaald.Ook de platformmigratie bood de nodige uitdagingen. Diverse utilitiesop de oude infrastructuur, zoals sorteringroutines met filterfunctiona-liteit, vereisen nabootsing op Windows. Bovendien verschillen de ka-raktersets op de oude infrastructuur en onder Windows van elkaar,hetgeen de nodige problemen tijdens de conversie en het testen oplevert, zoals extra benodigde conversie van testbestanden. Hoeheeft FloraHolland deze uitdagingen opgepakt en tot een goed eindegebracht zonder haar businessprocessen te verstoren?

InvesteringHet handmatig nabouwen van de Cobol-programma’s is een te lastigeen langdurige opdracht. En meestal accepteert de Business het niet wanneer gedurende een lange migratieperiode géén productiewijzi-gingen mogelijk zijn: de zogenaamde freeze-periode. Daarom is voorhet succesvol uitvoeren van complexe migraties automatisering vande conversie essentieel.

FloraHollandModerniseert Hart IT

FloraHolland, de grootste producent en handelaar van snijbloemen ter wereld, worstelde met een erfenis uit het

verleden. Verschillende Cobol-systemen op een oude infrastructuur kostten FloraHolland veel geld aan onderhoud

en beheer. Bovendien werd de technische kennis bij FloraHolland steeds schaarser om het onderhoud en beheer

adequaat uit te voeren. FloraHolland koos ervoor om het hart van haar IT te moderniseren door de Cobol-

systemen geautomatiseerd te laten migreren naar C# op een moderne infrastructuur.

FloraHolland koos ervoor om het hartvan haar IT te moderniseren door deCobol-systemen geautomatiseerd te laten migreren naar C# op een moderne infrastructuur

Statements van de bron- en doeltaalleken op het eerste gezicht dezelfdewerking te hebben, maar bleken uiteindelijk heel verschillend te zijn

Diverse utilities op de oude infrastructuur, zoals sorteringroutinesmet filterfunctionaliteit, vereisen nabootsing op Windows

magazine voor software development 29

Page 30: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

FloraHolland ging op zoek naar leveranciers die ervaring hebben metmigraties en hier geschikte tools voor hebben. Een grotendeels geautomatiseerde conversie van Cobol naar C# bleek echter nog nooiteerder te zijn uitgevoerd. De keuze van FloraHolland viel op de G4-tool van Cornerstone vanwege de goede basis die deze tool biedtvoor de ontwikkeling van een geautomatiseerde conversie van Cobolnaar C#. Vanuit Sogeti werd de migratiemethodiek Mikado™, inte-gratiecapaciteit en ruimschootse ervaring met migraties ingezet. Voorde toolontwikkeling stelde Sogeti de conversieregels op, die Corner-stone in zijn conversietool implementeerde.

Mikado™Mikado™ is een door Sogeti ontwikkelde migratieaanpak, gebaseerdop vele jaren ervaring. Mikado™ is ontwikkeld om migratieprojectenbeheerst en gecontroleerd uit te voeren. Migraties worden daarbij ge-zien als een projectmatig proces, waarbij middels een één-op-ééntransformatie de functionaliteit van de bestaande (bron-) naar eennieuwe (doel)omgeving wordt overgezet en waarbij de continuïteit in debedrijfsvoering wordt gegarandeerd. Vaak is er sprake van systemendie zijn ontwikkeld met ‘verouderde’ of achterhaalde technologie, dieuiteindelijk niet meer voldoen aan de eisen en wensen van deze tijd endie vaak hoge kosten met zich meebrengen. Hierdoor ontstaat denoodzaak om de systemen en/of data over te zetten naar een mo-dernere omgeving, eventueel met architectuurvernieuwing, en met behulp van analyse- en conversietooling.

Eerste helftSogeti initieerde het migratieproject en startte het volgens Mikado™op: na een migratiescan (in Mikado-termen “Scenario analyse”) vondde projectinrichting plaats en startte het opstellen van de conversie-regels en het parallel implementeren van de conversieregels in de G4-tool van Cornerstone. Het opstellen van de conversieregels bleek eenlastig en langdurig proces te zijn, met veel iteraties en veel uitzonde-ringen. Met name het vertalen van de dataopslagstructuur in Cobolnaar een object-oriented opslagstructuur in C# was te geïsoleerd, perprogrammadeel, opgepakt en niet als totaalconcept uitgewerkt. Na een lang traject was het nog steeds niet mogelijk om vanuit een automatische conversie een programma te compileren, terwijl de verzameling conversieregels al flinke proporties aannam.Door het niet kunnen compileren was er ook geen zicht op de kwali-teit van de conversie qua functionaliteit: is de output van de gecon-verteerde programma’s wel identiek aan die van de oorspronkelijke?

Wisselen van spoorVoor de ontwikkeling van een conversietool is het aan te raden omeerst een representatief programma volledig handmatig te converte-ren. Hieruit kunnen vervolgens de conversieregels worden afgeleid.Dit spoor is ook initieel bewandeld, maar vanwege tijdsdruk losgela-ten. Het terugwisselen naar deze aanpak, maar met als uitgangspuntde al voor meer dan 90% automatisch geconverteerde programma’s,doorbrak deze impasse. De resterende 10% van enkele representa-tieve programma’s werd handmatig afgebouwd, totdat ze compileer-baar waren. Vóór het handmatig afbouwen zijn afspraken gemaakt

over de vertaling van de data-opslagstructuur en over de vertaling vande utilities op de oude infrastructuur, zodat deze meteen in het hand-matig afbouwen meegenomen konden worden. Het resultaat was en-kele compileerbare en testbare representatieve programma’s. Doormiddel van een functionele test werd de kwaliteit van de conversieaangetoond. Dit was tevens het punt waarop gewisseld kon wordennaar het opstellen en implementeren van de ontbrekende conversie-regels op basis van de handmatige afbouw. Hierdoor is de conversie-tool gecompleteerd en kon de hoofdconversie op een beheerstemanier worden uitgevoerd.Het blijkt dus essentiëel te zijn om een Proof of Concept uit te voerenop een representatief deel van de te migreren systemen, om zodoendede complexiteit naar voren te halen, en daarmee de risico’s van het migratieproject te minimaliseren.

Tweede helftDe gewijzigde aanpak maakte de resterende projectinspanning met-een meetbaar. Er konden goede schattingen worden gemaakt voorhet implementeren van de resterende conversieregels, het testen enhet bugfixen. Ook het kleine restant aan handmatige acties om de uit-zonderingen in de geconverteerde programma’s te coderen werd di-rect inzichtelijk. De gewijzigde projectplanning werd in één klaprealistisch en dus voorspelbaar. Na enkele kleine overschrijdingen vantussenmijlpalen vond de eindoplevering enkele werkdagen voor degeplande datum plaats. Het realiseren van de vereiste functionaliteit en

performance staat echter altijd op de eer-ste plaats. Uit het beperkte aantal bevin-dingen (minder dan één pergeconverteerd programma) blijkt datzowel de proces- als productkwaliteit vande tweede helft van het project dik in ordewaren. FloraHolland heeft op basis van deacceptatietest en na het oplossen van debevindingen de migratie geaccepteerd. Dein productie name van de geconverteerdeprogramma’s verliep zonder noemens-waardige problemen.

Ná de finishHet FloraHolland migratieproject leverde een aantal waardevolle erva-ringen op die in Mikado™ zijn geïntegreerd. De opgerichte unit Migratie Services is verantwoordelijk voor de integratie van deze mi-gratieleerpunten. Doordat elke projectmanager van een migratieprojectverplicht is om zijn ervaringen aan te leveren en omdat alle migratie-projecten waarin Sogeti betrokken is volgens de Mikado™ methodeworden aangepakt, zorgt de borging van deze ervaringen ervoor datniet opnieuw dezelfde knelpunten kunnen ontstaan. •

Norbert Mimpen

Norbert Mimpen is Projectmanageren Migratie Specialist bij Sogeti.Norbert maakt deel uit van de unitMigratie Services, van waaruit hij inalle fasen van migratieprojecten betrokken is, vanaf het eerste klant-contact tot en met de afronding.Norbert draagt verder bij aan deproductontwikkeling van migratiesen is docent van migratieopleidin-

gen. Norbert is een begenadigd hardloper en is een paar wekenper jaar te vinden in Brazilië.

CORESYSTEMS

MAGAZINE30

Page 31: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

DOTNET

NUKEBrandon Haynes

Authorization, Authentication, and ProvidersPrior to delving into the details of authorization in DotNetNuke, it is important to distinguish the often-confused difference between authentication – the binding of an identifier and one or more creden-tials (e.g., a password) to a principal (e.g., a user) – and authorization,which is the process of verifying that a principal is indeed allowed toperform an action or access a resource. Herein we focus upon thislatter function.Authentication (and, as we shall soon see, authorization) is customi-zable in the DotNetNuke framework through classes configured viathe provider pattern. This pattern allows runtime selection and confi-guration of a provider so long as that class conforms to the expectedinterface (or, less frequently, base class) (1). DotNetNuke relies heavilyon this pattern to effectuate extendibility for the services (data, membership, navigation, et cetera) upon which it relies.

Why Allow Authorization to Be Extended?Before we touch on the details associated with the abstraction of authorization in the DotNetNuke framework, it is worth exploring whysuch a change would be made. For the DotNetNuke Corporation, theanswer is simple: granular permissions are one of the differentiatingfactors planned between the Professional and Community Editions(2). Consumers of the former will be able to assign permissions at thevery detailed level required by many enterprise customers (to whomthat edition is targeted), while Community Edition deployments willcontinue to benefit from the (robust) level of authorization that has always been available on the platform.

But, just as the DotNetNuke Corporation will leverage this extensionpoint for its enterprise customers, so too may any developer. This willultimately allow both for third-party extensions to accommodate com-mon advanced scenarios, and custom development for specific one-off situations. This enhancement is an improvement for all involved.

In addition to the benefits described above, the consolidation of aut-horization services into a single, dedicated class allows for a reducedsecurity surface area and thereby serves to increase overall frameworksecurity. Whereas in the past there might have been several places toattack authorization logic, this functionality will now be consolidatedinto a single-purpose assembly dedicated to one task.

Authorization Prior to Version 5.1Having discussed the reasons why authorization was abstracted, wenow examine the state of authorization in DotNetNuke prior to version5.1. Before this version, authorization logic was internal to the frame-work (located in the DotNetNuke.Security.Permissions namespace)and not extendable or customizable by developers in any way (save fora draconian recompilation of the entire core framework). For example,module permission-related logic was contained within the Module-PermissionController class, while file-based authorization was handledentirely by the FilePermissionController. The methods in these classeswere static, not virtual, and not customizable in any manner, as is de-monstrated in the ModulePermissionController.HasModulePermissionmethod detailed in listing 1.

Public Class ModulePermissionController

...

Public Shared Function HasModulePermission(...) As Boolean

Return PortalSecurity.IsInRoles(...)

End Function

...

End Class

Listing 1: Pre-5.1 implementation of ModulePermissionControl-ler.HasModulePermission (simplified for reading). This method isstatic and not customizable without modifying the core DotNetNukeframework.

While it does perhaps make some sense for these authorizations to beperformed by those controller classes that utilize the functionality, thisapproach makes it difficult to adjust, extend, and refine the frameworkfor novel or unforeseen design requirements. Decoupling policy-en-forcement functionality from its authorization-related counterpart doeshave some attractive design characteristics, including cleaner overallseparation of concern.

Authorization in DotNetNuke 5.1Authorization services in version 5.1 have been abstracted into a separate provider assembly and the relevant functionality has been

Under the Hood:Provider-Based Authorization in DotNetNuke 5.1Beginning with version 5.1, DotNetNuke intro-duces provider-based authorization as a first-class framework extension point. Prior to thisenhancement, authorization in DotNetNuketook place entirely within the core (generally implemented through classes in the DotNet-Nuke.Security.Permissions namespace) andwas not customizable in any way. Herein weexplore the motivations, implementation, andconfiguration associated with these changes,and discuss what this might mean for futurecustomization.

This will ultimately allow both for third-party extensions to accommodatecommon advanced scenarios, andcustom development for specific one-off situations

magazine voor software development 31

Page 32: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

moved therein. The out-of-the-box provider included with the Community Edition is defined as DotNetNuke.Security.Permissi-ons.CorePermissionProvider. The class diagram in figure 1 depicts therelationship of this class to the core framework.

Fig. 1: Class diagram demonstrating the relationship between thecore framework controller classes, the PermissionProvider class,and the concrete CorePermissionProvider authorization implemen-tation.

Unlike many other DotNetNuke providers, the permission provider isnot interface-driven, and must currently be inherited from DotNet-Nuke.Security.Permissions.PermissionProvider (though as of presstime this version was still in beta and the final architecture remainssubject to change). This is somewhat unfortunate as it potentially com-plicates some testing patterns (in particular the ability to easily mocka custom provider), but may nonetheless be generally worked aroundto meet most design goals.

Like all the other DotNetNuke providers (e.g., data, membership, pro-file), the permission provider is configured in the web.config. The de-fault configuration is presented in listing 2. Any custom provider wouldrequire a new entry under the <providers> node with the desired type(and the containing assembly must be deployed into the application’sbin directory).

<configuration>

...

<dotnetnuke>

...

<permissions defaultProvider="CorePermissionProvider">

<providers>

...

<add name="CorePermissionProvider"

type="DotNetNuke.Security.Permissions.

CorePermissionProvider..."

providerPath="..." />

</providers>

</permissions>

</dotnetnuke>

</configuration>

Listing 2: Default web.config Configuration for the 5.1 PermissionProvider (with extraneous details omitted)

The existing classes that utilized previously-internal permission functionality have been modified to operate against the new provider.For example, the TabPermissionController was modified to route authorization to the provider instance via a provider.HasTabPermis-sion call (listing 3). The provider itself has assumed the functionalitypreviously implemented directly in the TabPermissionController class,an example of which is shown in listing 4.

Public Shared Function HasTabPermission(...) As Boolean

Dim hasPermission As Boolean = Null.NullBoolean

If permissionKey.Contains(",") Then

For Each permission As String In permissionKey.Split(",")

If provider.HasTabPermission(objTabPermissions,_

permission) Then

hasPermission = True

Exit For

End If

Next

Else

hasPermission = provider.HasTabPermission_

(objTabPermissions, permissionKey)

End If

Return hasPermission

End Function

Listing 3: TabPermissionController.HasTabPermission modified inversion 5.1 to utilize the new permission provider. Note that this method routes all authorization decisions to the provider (accessedthrough a private field named “provider”).

Public Overridable Function HasTabPermission(...) As Boolean

Return PortalSecurity.IsInRoles(...)

End Function

Listing 4: The HasTabPermission method of the default CommunityEdition permission provider class, which has subsumed the func-tionality that was previously internal to the core.

The DotNetNuke 5.1 Permission Provider ImplementationThe DotNetNuke 5.1 authorization provider may be generally subdivided into three classes of authorization: folder permissions, module-related permissions, and page-related permissions. Each ofthese groups contains a number of overridable methods as outlinedin table 1. These methods generally indicate whether a user may perform a particular action (e.g., CanDeleteModule returns a Booleanindicating whether a user may delete a particular module instance),with a few exceptions that update, delete, or apply to collections ofpermission objects.

Category Overridable MethodsModule Permissions CanAdminModule

CanDeleteModuleCanEditModuleContentCanExportModuleCanImportModuleCanManageModuleCanViewModuleDeleteModulePermissionsByUserGetModulePermissionsHasModulePermission

Page Permissions CanAddContentToPageCanAddPageCanAdminPageCanCopyPageCanDeletePageCanExportPageCanImportPageCanManagePageCanNavigateToPageCanViewPageDeleteTabPermissionsByUser

Folder Permissions CanAdminFolderCanAddFolderCanCopyFolder

DOTNET

NUKE

MAGAZINE32

Page 33: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

CanDeleteFolderCanManageFolderCanViewFolderDeleteFolderPermissionsByUserGetFolderPermissionsCollectionByFolderHasFolderPermissionSaveFolderPermissions

Table 1: Methods available in the DotNetNuke 5.1 permission provider

While an understanding of how the core framework performs authorization is important for those who wish to better understandhow DotNetNuke works, it is worth mentioning that a module develo-per typically will not utilize this provider directly. Instead, modulesshould continue to use the methods exposed by the relevant control-ler (e.g., TabController.HasTabPermission). The information presentedherein is especially important, however, for those who wish to extendor augment authorization services.

Extending Authorization ServicesDevelopers who wish to extend or enhance the built-in DotNetNukeauthorization services will likely do so via simple inheritance (whenbase functionality is largely sufficient), decoration (for runtime flexibilityin authorization functionality), or adaptation (to allow a foreign authentication system to be used within the DotNetNuke framework).In many cases some combination of these design patterns might beselected for advanced integration requirements.

The ability to extend DotNetNuke using authorization as a first-classextension point allows for a number of interesting possibilities. Forexample, the page-related authorization methods may be utilized toallow users belonging to one portal to be able to edit the pages onanother. In addition to these obvious direct permission manipulations,more esoteric enhancements might include STS federated authoriza-tion using the new Microsoft Geneva framework or even the enablingof Amazon S3 as a backing store for files (although authorization wouldonly be one piece of this particular puzzle).

The Bottom LineThe decision to offer authorization services as a first-class extensionpoint on the DotNetNuke platform is an important step forward, andallows for customization that is sure to be filled by third-party extensi-ons to cover novel requirements. For developers, an appreciation ofhow this provider is implemented, utilized, and configured is an important part of understanding the framework as a whole.

References1. Howard, R. Provider Model Design Pattern and Specification.

Microsoft Developer Network. [Online] March 4, 2004. [Cited:May 24, 2009.];http://msdn.microsoft.com/en-us/library/ms972319.aspx.

2. Willhite, S. RE: Granular Permissions Stripped from DNN5 Community Edition? DotNetNuke. [Online] April 30, 2009. [Cited:May 24, 2009.];http://www.dotnetnuke.com/Default.aspx?ThreadId=305055&Scope=Posts&TabId=795. •

For developers, an appreciation of how this provider is implemented, utilized, and configured is an important part of understanding the framework as a whole

Brandon Haynes

Brandon Haynes (brandonhay-nes.org) is a member of the Dot-NetNuke core team, and servesprimarily by providing security-rela-ted guidance. He is the chief execu-tive officer at Everysport.net Inc.,which delivers enterprise resourceplanning, web-presence, e-com-merce, and integration-related func-

tionality to recreational facilities. A graduate of the University ofIllinois at Urbana-Champaign - consistently ranked among thetop-five computer-science programs worldwide - Brandon has along history of intellectual curiosity and accomplishment. Withmore than twenty years of experience in software development,Brandon’s professional interests are currently focused on thenexus between intellectual property law, technology, and business. He is currently pursuing a graduate degree at HarvardUniversity.

DOTNET

NUKE

UX TIP:

Alternatief voor Silverlight Badge

Bij het maken van een Silverlight applicatie wordt de ‘install ex-perience’ nog wel eens over het hoofd gezien. De standaardknop die door Visual studio meegeleverd wordt nodigt een be-zoeker niet uit om de plugin te downloaden. Probleem hiervanis dat bezoekers deze knop niet begrijpen en denken dat heteen banner - dus reclame! - is. Doordat er geen informatie tevinden is over de applicatie nemen ze niet de moeite om de Sil-verlight plugin te downloaden. Ze kunnen zelfs bang zijn om deplugin te downloaden: hebben we immers niet geleerd niet zo-maar alles te installeren?Om te voorkomen dat bezoekers je pagina verlaten zonder deplugin te downloaden en de Silverlight experience die je ze wiltbieden mislopen, hierbij de volgende tips:• Maak het gemakkelijk voor de gebruiker om de plugin te

downloaden; maak b.v. een custom button;• Geef duidelijk aan dat Silverlight en de plugin een

Microsoft product is en daarmee veilig te downloaden;• Geef een korte beschrijving van de applicatie;• Laat de gebruiker zien wat ze kunnen verwachten,

b.v. via een afbeelding als de volgende:

magazine voor software development 33

Page 34: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

DELPHI Bob Swart

van de async method. En de main thread die de async method aanroept zou niet kunnen weten wanneer het resultaat daadwerkelijkbeschikbaar is.Dit leidt al snel tot de vraag waar en wanneer een async method dannuttig kan zijn. In praktijk gebruik ik het veel in situaties waar je ietswilt doen dat verder zonder interactie kan worden afgewerkt. Het ge-nereren en/of printen van een report bijvoorbeeld, of het versturen vaneen e-mail. Dan is het ideaal dat de aanroep van de async methodgeen verdere tijd in beslag neemt en de main thread gewoon doorgaat.

Async CodeBehalve async methods kunnen we het async keyword ook gebruikenom van blokken code aan te geven dat deze asynchroon (in eenaparte thread) moet worden uitgevoerd. Dit kan bijvoorbeeld als volgt:

class method ConsoleApp.Main;varx: Integer;

beginx := 42;

async beginx := x + x;Console.WriteLine('x = ' + x.ToString);

end;

x := x / 2;Console.WriteLine('x = ' + x.ToString);Console.ReadKey

end;

Ook hierbij geldt dat het async code block geen persistente wijzigin-gen kan aanbrengen in lokale variabelen. In bovenstaand voorbeeldwordt de variabele X echter wel aangepast. Om hiermee (concurrency)problemen te voorkomen wordt, voordat het async code block start,eerst de gehele context gekopieerd. In dit geval is dat alleen de variabele X, maar dat kan in de praktijk heel wat meer zijn.De output van het stuk code is dan ook x = 84, en x = 21. Misschienin deze volgorde, of wellicht andersom (de x = 21 eerst). Ze kunnen intheorie zelfs door elkaar geschreven staan, maar dat heb ik zelf nogniet kunnen reproduceren.

Behalve het feit dat de variabele x in het async code block niet deechte x is, maar een kopie, is het ook niet gegarandeerd wanneer hetasync code block klaar is. Maar daar is wel een oplossing voor: wekunnen het gehele async code block toekennen aan een System.Ac-tion variabele en die gebruiken om op een bepaald moment deze va-riabele als statement aan te roepen waarna - indien het async codeblock nog niet klaar is `- gewacht wordt tot deze thread afgerond is.

Dat gaat dan als volgt:

class method ConsoleApp.Main;

var

x: Integer;

begin

MAGAZINE34

Delphi Prism:Async, Futures en Parallele MogelijkhedenDelphi PrismDelphi Prism is de nieuwe .NET variant van Delphi, en bestaat uit drie onderdelen. Allereerst is daar de Oxygenecompiler, gemaakt en onderhouden door RemObjectsSoftware (destijds uitgebracht onder de naam Chrome).Deze Oxygene compileer draait als een plug-in in de Microsoft Visual Studio IDE (de gratis Shell of Express edi-tie is voldoende), en levert daarmee als tweede onderdeelalle designers voor WinForms, WPF, ASP.NET, Silverlight,etc. Behalve een Compact Framework designer dan,omdat die nog steeds vastgebakken zit aan C# of VB. Hetderde onderdeel van Dephi for .NET is het enige deel datnog van CodeGear afkomstig is: de database connectivityin de vorm van de dbExpress drivers en DataSnap mogelijkheden. Op dit moment beperkt tot InterBase enBlackfishSQL voor dbExpress drivers, en alleen nog DataSnap clients, maar in toekomstige uitbreidingen kunnen we extra dbExpress drivers en DataSnap serverfunctionaliteit verwachten.

AsyncDe Oxygene compiler van Delphi Prism ondersteunt een taal die hetasync keyword bevat. Dit keyword kan gebruikt worden om bij eenmethode aan te geven dat deze asynchroon moet worden uitgevoerd;in een aparte thread dus. De declaratie van een asynchrone methodkan als volgt zijn:

method DoeIetsMetInputParameters(x,y,z: Integer); async;

Let op dat we in Delphi Prism geen procedure of function meer hoeven te schrijven, maar het generiekere method-keyword kunnengebruiken. En voor een asynchrone methode voegen we het keywordasync toe aan het eind van de declaratie.

Zoals de naam van de method al doet vermoeden, heeft een asyncmethod een voordeel maar ook een aantal beperkingen. Het grotevoordeel is uiteraard dat de main thread meteen terugkeert na de aanroep van de async method. De async method zal in een apartethread uitgevoerd worden, waardoor de main thread meteen verderkan. Nadeel daarbij is dat de main thread niet zal weten wanneer deasync method is afgelopen. Daarnaast kan de method alleen maarinput parameters bevatten, en geen resultaat terugeven omdat dezenatuurlijk pas bekend worden tijdens of na afloop van het uitvoeren

De database connectivity is het enigeonderdeel van Dephi for .NET dat nogvan CodeGear afkomstig is

Page 35: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

magazine voor software development 35

DELPHI

x := 42;

var xtask := async beginx := x + x;Console.WriteLine('x = ' + x.ToString); // 21

end;

x := x / 2;Console.WriteLine('x = ' + x.ToString); // 84xtask(); // wachten tot de thread klaar isConsole.ReadKey

end;

De aanroep van xtask() zal er nu voor zorgen dat er op dat moment ge-wacht wordt – indien nodig – tot het async code block dat we aanxtask hebben toegewezen is uitgevoerd. Die truc kunnen we helaasniet uithalen met async methods, maar alleen met async code blocks.

FuturesNadeel van een async code block blijft dat je wel iets kunt doen of uit-rekenen, maar het resultaat niet meer kunt “terugzetten” naar de mainthread. Het async code block wordt als het ware in een eigen wereldjeuitgevoerd, met een kopie van de omgeving.Als we wel nog iets terug willen geven, maar ook gebruik willen maken

van de kracht van asynchrone code, dan moeten we een andere Delphi Prism feature gebruiken: het future keyword. Door gebruik temaken van dit keyword geven we aan dat een variabele een waardeheeft die op dit moment nog niet bekend is (bijvoorbeeld omdat detoekomstige waarde ervan in een async code block of method wordtberekend), maar op het moment dat we hem nodig hebben, zal dewaarde er zijn (of blijven we erop wachten).

Stel bijvoorbeeld dat we voor een hypotheekberekening twee maand-bedragen bij elkaar moeten optellen: het rente bedrag en het premiebedrag. Beide bedragen zijn afkomstig uit een wellicht complexe berekening, en het zou zonde zijn om die op elkaar te laten wachten.Zeker als je een dual-core of multi-processor machine hebt en eendeel ervan toch niks staat te doen.De syntax van het gebruik van futures voor dit voorbeeld is als volgt:

method MainForm.BerekenMaandbedrag: Double;var

RenteBedrag: future Double;PremieBedrag: future Double;VerborgenKosten: Double;

beginRenteBedrag := async BerekenRenteBedrag;PremieBedrag := async BerekenPremieBedrag;VerborgenKosten := BerekenVerborgenKosten;Result := RenteBedrag + PremieBedrag + VerborgenKosten

end;

Zowel de waarde van RenteBedrag als die van PremieBedrag wordenin aan aparte thread berekend. Door dat op deze manier te doen zijnde waardes waarschijnlijk nog niet bekend als we aan de verborgenkosten berekening gaan beginnen. Maar dat maakt niet uit, want ophet moment dat we alles nodig hebben (bij het Result statement) zalblijken of de async code al klaar is, en de future variabelen hun waardeal hebben, of dat we daar nog even op moeten wachten. Je zou in decode eventueel een soort indicator op het scherm aan kunnen zetten(“waiting…”) voordat je de waarde van een future variabele ophaalt (oferop blijft wachten), zodat de gebruiker in ieder geval door heeft water aan de hand is als we hier enige tijd moeten wachten tot de waardevan de future bekend is.

In feite is de xtask variabele die we eerder gebruikten om op een asynccode block te wachten ook een future. En het “aanroepen” van de variabele is niets anders dan het gebruiken van de waarde, waardoorwe blijven wachten indien deze (het resultaat van het code block) nogniet bekend is.

PFX Framework: Threads vs. TasksDe async voorbeelden runnen in een eigen thread, in de .NET threadpool. Echter, de volgende versie van het .NET Framework bevat eenPFX Framework voor Parallele Extensies, en als we dat erbij gebruikenzal de async method of code als een echte parallele task draaien inplaats van alleen maar als een nieuwe thread in the thread pool.

ParallelEen nieuwe feature die verbonden is aan het PFX Framework is het parallel keyword. Hiermee kunnen we aangeven dat een stuk codeparallel uitgevoerd moet worden, b.v. een for-loop die in stukken geknipt zal worden.

method MainForm.Doe;beginfor parallel i: Integer := 0 to 10 dobeginBerekenIetsMetI(i);

end;end;

Deze code zal alleen compileren als het PFX wordt aangetroffen (debenodigde assemblies zijn nodig), en zal ook alleen draaien op machines waar de PFX aanwezig is.Meer experimenten met PFX en het parallel keyword (waarin we zullen zien hoe de loop in stukken wordt geknipt, en wat er met de igebeurt) zullen volgen als ook de ontwikkeling aan .NET 4.0 en PFXwat meer gevorderd is. Het goede nieuws is dat Delphi Prism nu aldeze komende features ondersteunt.

ConclusieIn dit artikel heb ik laten zien hoe enkele taalelementen van DelphiPrism werken - taalelementen zoals async en futures die overigens alenige tijd in de Oxygene compiler zaten, dus niet zo heel verschrikke-lijk nieuw zijn. Het leuke is in ieder geval dat Delphi for .NET niet lan-ger “achterloopt” op het gebied van .NET features, maar juist nu algebruik maakt van functionaliteit die nog niet eens af is of volledig beschikbaar. Wie nog vragen of opmerkingen heeft, of Delphi Prismzelf een keer wil proberen, kan me altijd per e-mail bereiken [email protected]. •

We maken gebruik van een andereDelphi Prism feature: het future keyword```

Bob Swart

Bob Swart is werkzaam in de ITsinds 1983 en heeft daarbij eenvoorliefde voor (Turbo) Pascal enDelphi. Bob spreekt regelmatig op(internationale) conferenties overDelphi en heeft honderden artikelengeschreven, alsmede zijn eigen Del-phi cursusmateriaal voor Delphi trai-ningen en workshops. Behalve voorhet geven van trainingen, is Bob ook

beschikbaar voor consultancy, coaching, ontwerp- en bouw-werkzaamheden, of andere ondersteuning op het gebied vansoftware ontwikkeling met Delphi - voor zowel Win32 als .NET.Sinds de zomer van 2007 is Bob ook reseller van CodeGear pro-ducten zoals Delphi en RAD Studio. Bob Swart Training & Con-sultancy is gevestigd in Helmond Brandevoort, en beschikt overeen eigen trainingsruimte van ruim 42 vierkante meter, inclusiefeen testlab voor alle mogelijke toepassingen. De voorliefde vanBob voor Pascal en Delphi heeft hij ook tot uiting laten komen inde namen van zijn kinderen Erik Mark Pascal en Natasha LouiseDelphine.

Page 36: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

Advertentie Microsoft

Page 37: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

Advertentie Microsoft

Page 38: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

Gustavo Velez

The SharePoint Object Model offers spell check as a webservice tocontrol the orthography in different languages, providing suggestionsand alternatives to correct errors. It’s important to point out that theservice is not equal to the system used by other Office products. Consequently - as an on-line server - the SharePoint system is less ad-vanced, and provides limited functionality in contrast to the defaultspell check of Word or Excel; for example, there is no possibility tocheck grammar nor does it offer a thesaurus. MOSS uses spell check in various locations; for example, in each Listwhere there are text fields there is a “Spelling” button in the horizon-tal tools bar. When you click on the button, a popup window appearsallowing you to loop through the words on the page, making a comparison with the internal dictionary and displaying words with errors, together with suggestions to rectify them.

Fig. 1: SharePoint List with the Spelling button and popup window

The same window allows users to select the language and dialect forthe corrector (the configured default language is initially used). Thecorrector only compares words with the internal dictionary, withoutgrammar or syntax corrections. Another disadvantage is that it is notpossible to add new words to the dictionary; to circumvent that situation a list of words can be created that will be ignored by the corrector, in fact a specially-designed dictionary .

Webservice All the corrector’s functionality is available as a default Microsoft OfficeSharePoint Server (MOSS) webservice. The “SpellCheck.asmx” webservice has three input parameters:• “chunksToSpell”: an array of strings with the texts to check;• “declaredLanguage”: an integer that gives the language identifier to

be used by the checker. This identifier is not the same as that usedby SharePoint for its internal configuration; the values can be foundon the Microsoft sitehttp://msdn2.microsoft.com/en-us/library/0h88fahh.aspx;use the value of the column “decimal value”;

• “useLad”: a boolean that indicates if the spell check should detectthe MOSS default language.

At first glance, the webservice is very straightforward to apply following a simple sequence: create a reference, give the service usercredentials, configure the input parameters and execute the service.Unfortunately, the MOSS implementation has two crucial errors thathamper its use.First, if the parameter “useLad” is employed in such a way that spellcheck uses the default MOSS language, the checker will apply thelanguage identifier of MOSS, not the target language identifier to bechecked. This is not a problem in English, because the two languageidentifiers are the same (1033), but in other languages it is always dif-ferent. For example, in Spanish the webservice will use 3082 (MOSSLanguage Identifier for Spanish) instead of 1034 (Language Identifierfor Spanish Spell Check). Consequently, the corrector never providesaccurate results in languages other than English.

To avoid this problem, declare the “useLad” parameter as false andgive the correct language identifier in the “declaredLanguage” para-meter. The downside to this workaround is that you always need touse a constant identifier or you must create a lookup table with the ne-cessary logic to link the MOSS language identifier to the spell checklanguage identifier.

The second problem may be more serious. Because the webservicehas irregularities in the code, vocabulary suggestions are not

MAGAZINE38

Spell Check in

SharePoint 2007SharePoint is Microsoft’s server dedicatedto the interchange of information and thusa system where writing is a critical compo-nent. As with other Office family products,Microsoft Office SharePoint Server (MOSS)provides tools to check and correct the or-thography in texts. The service is used insome default components of MOSS, allowing developers to utilize it in customsoftware, such as WebParts or specializedpages.

At first glance, the webservice is verystraightforward to apply

INFORMATIONWORKER

Page 39: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

magazine voor software development 39

provided. To resolve this problem it is obligatory to call the webser-vice using the methods of the class “HttpWebRequest” from the NameSpace “System.Net”, creating the SOAP envelope and XMLquery manually, as outlined in the following paragraphs.In the source code where the webservice will be called, create references (“using” in CSharp) to System, System.IO, System.Net,System.Text and System.Xml. The code lines below call the webservice using the HttpWebRequest class:

StringBuilder myStringBuilder = new StringBuilder(EnvelopeSoap);

int index = myStringBuilder.ToString().IndexOf("</soap:Body>");

myStringBuilder.Insert(index, MyQuery);

XmlDocument EnvelopeSoapXml = new XmlDocument();EnvelopeSoapXml.LoadXml(myStringBuilder.ToString());

HttpWebRequest myQueryWeb =(HttpWebRequest)WebRequest.Create(UrlChequerWS);

myQueryWeb.UseDefaultCredentials = true;myQueryWeb.Headers.Add("SOAPAction", AccionSoap);myQueryWeb.ContentType = "text/xml;charset=\"utf-8\"";myQueryWeb.Accept = "text/xml";myQueryWeb.Method = "POST";

using (Stream myStream = myQueryWeb.GetRequestStream()){

EnvelopeSoapXml.Save(myStream);}

IAsyncResult ResultAsync = myQueryWeb.BeginGetResponse(null, null);

ResultAsync.AsyncWaitHandle.WaitOne();

string ResponseSoap = string.Empty;using (WebResponse ResponseWeb =

myQueryWeb.EndGetResponse(ResultAsync))using (StreamReader myStreamReader =

new StreamReader(ResponseWeb.GetResponseStream())){

ResponseSoap = myStreamReader.ReadToEnd();}

Listing 1: Calling the webservice using the HttpWebRequest class

In the code, create a StringBuilder that contains the SOAP call to thewebservice. The SOAP envelope is directly added by using the syntax:

static string EnvelopeSoap = @"<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body></soap:Body></soap:Envelope>";

Listing 2: Adding the SOAP envelope

Then, immediately before closing the envelope, add the XML querywith the following syntax:

static string MyQuery = @"<SpellCheckxmlns='http://schemas.microsoft.com/sharepoint/publishing/

spelling/'><chunksToSpell>

<string>This rou</string><string> has an error </string>

</chunksToSpell><declaredLanguage>1033</declaredLanguage><useLad>false</useLad></SpellCheck>";

Listing 3: XML query

There are two strings in the query that need to be adjusted, namely“This rou” and “has an error”. The language identifier is declared (1033)and the MOSS language identifier must be blocked with the code“useLad=false”. As stated earlier, at this point you need to define thespell check language identifier if you are using a language other thanEnglish.After the creation of the envelope and the query in a string, they areconverted to a XmlDocument that can be used in the service call. Theobject “myQueryWeb” (of the “HttpWebRequest” type) is created usingas input parameter the URL of the spell check webservice:

static string UrlChequerWS = "http[s]://

ServerName/_vti_bin/SpellCheck.asmx";

The object receives the default credentials of the user, the contenttype, the type of the method to be used, and finally, the form to sendthe envelope. The SOAP action type is added to the header in the following manner:

static string AccionSoap = "http://schemas.microsoft.com/”+

“sharepoint/publishing/spelling/SpellCheck";

With this action, the envelope is assigned to the webservice call andusing the interface, IAsyncResult, the anticipated result is asynchro-nous; this avoids a delay in the functioning of SharePoint while awaiting the response.Finally the call to the webservice is executed and the results comeback in the form of a “WebResponse” object that is converted to a“StreamReader” which needs to be interpreted; the final result is aXML string “ResponseSoap”. The response of the example is in theform:

<?xml version="1.0" encoding="utf-8" ?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=http://www.w3.org/2001/XMLSchema<soap:Body><SpellCheckResponsexmlns="http://schemas.microsoft.com/sharepoint/publishing/spelling/">

<SpellCheckResult><errorCode>Ok</errorCode><detectedLanguage>1033</detectedLanguage><spellingErrors><SpellingErrors><chunkIndex>0</chunkIndex><flaggedWords><FlaggedWord><word>rou</word><type>UnknownWord</type><offset>3</offset>

</FlaggedWord></flaggedWords>

</SpellingErrors></spellingErrors><spellingSuggestions><SpellingSuggestions><word>rou</word><sug>

<string>roue</string><string>rout</string><string>roux</string><string>roe</string><string>row</string><string>rob</string>

</sug></SpellingSuggestions>

</spellingSuggestions></SpellCheckResult>

</SpellCheckResponse></soap:Body>

</soap:Envelope>

INFORMATION

WORKER

Page 40: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE40

In the SOAP response note that the corrector - in the first string(chunkIndex=0) - has identified an unknown word (FlaggedWord-word=rou), that probably has an error in the third character (offset=3).The suggestions section indicates that the unidentified word has sixpossible corrections in the dictionary. The second string is not foundin the response, signifying it is accepted by the corrector.

The remaining code implementation is elemental and can be used ineach SharePoint component (WebParts, WebControls, Web pages,etc). The last task is to extract the relevant information from the XMLresponse and present it to the user in the desired way.

Spell Check Default components It is not necessary to use webservice spell check directly, as indicatedin the last section; it is also possible to use the existing SharePoint de-fault infrastructure for this purpose. The default implementation of spellcheck for MOSS is based in one APSX-page and two JavaScript-files:• SpellChecker.aspx: (C:\Program Files\Common Files\Microsoft Sha-

red\web server extensions\12\TEMPLATE\LAYOUTS\SpellChec-ker.aspx) contains the Web page used to show words with errorsand the suggestions (shown in figure 1);

• SpellChecker.js: (C:\Program Files\Common Files\Microsoft Sha-red\web server extensions\12\TEMPLATE\LAYOUTS\3082\Spell-Checker.js) contains the routines to call the webservice, show andrectify words with errors;

• SpellCheckerEntirePage.js: (C:\Program Files\Common Files\Mi-crosoft Shared\web server extensions\12\TEMPLATE\LAY-OUTS\3082\SpellChecker.js) works as a link between theASPX-page and the routines of the JavaScript in SpellChecker.js.

In the event the language cannot be detected, the ASPX-page initiallyshows a menu to select it from the available languages list.The default MOSS corrector page can be initiated from each ASPX-page as well. To view the process, create a new file with the .ASPX ex-tension (“spellcheck.asp” for example) in the directory “C:\ProgramFiles\Common Files\Microsoft Shared\web server extensions\12\TEM-PLATE\LAYOUTS\”. Open the file with any ASCII text editor (Note Pad)and add a reference to the SharePoint assembly:

<%@ Register Tagprefix="SharePoint"

Namespace="Microsoft.SharePoint.WebControls"

Assembly="Microsoft.SharePoint,

Version=12.0.0.0,

Culture=neutral,

PublicKeyToken=71e9bce111e9429c" %>

Then create references to the files with the JavaScripts:

<SharePoint:ScriptLink

language="javascript"

name="core.js"

runat="server" />

<SharePoint:ScriptLink

language="javascript"

name="SpellCheckEntirePage.js"

runat="server" />

And a JavaScript section to call Spell Check:

<script language="javascript" type="text/javascript">

function CheckSpell()

{

SpellCheckEntirePage('/_vti_bin/SpellCheck.asmx',

'/_layouts/SpellChecker.aspx');

}

</script>

Finally create the content controls where the user can write a text tobe checked. In the example it is one text box, but as many as are required can be created and spell check will loop through all of themscanning for errors. Use the syntax:

Some text to check &nbsp;&nbsp;

<input type="text" name="SomeText">

The button at the end will call the JavaScript and spell check:

<a href="javascript:" onclick="CheckSpell();">

Spell Checker

</a>

Call the ASPX from MOSS using the URL (“http[s]://ServerName/_lay-outs/ spellcheck.asp). After clicking the button, a popup window willappear showing the incorrect words and the correction suggestions:

Fig. 2: ASPX custom page using default spell check

With the code above, all the texts found on the page will be scanned.If you want to exclude any of the text from correction, use the attribute“excludeFromSpellCheck” in the HTML syntax. For example, to createa text box controlled by the server where no spell check is desired,use:

<asp:TextBox ID=”TextBoxNoControled” runat=”server”

excludeFromSpellCheck=”true” />

Note: The attribute ”excludeFromSpellCheck” can be used in a similar way in client-side controls using HTML code.

If necessary, it is also possible to modify the files SpellChecker.aspx,SpellChecker.js and/or SpellCheckerEntirePage.js, but it is not recommended or effective as any future Microsoft Service Pack canrevert the files to the original state.

Dictionary modificationsMOSS has default correction dictionaries for each supported languagebut it is impossible to modify them. However it is possible to addwords in such a way that they are not identified as errors.

INFORMATION

WORKER

Page 41: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

The following process creates a type of custom dictionary for thesewords:• Create a new Document Library “Spelling” at the root of the Portal;• Create a text file “Custom Dictionary.txt” locally;• Add all the words that should not be recognized as spelling errors

in the text file, one word per line;• Upload the text file to the newly-created Library above.

Only one “Custom Dictionary” Document Library is possible for eachsite collection; the names of the library and text file need to be exactlyas indicated and the library must be located at the root of the portal.

ConclusionA valuable feature of SharePoint 2007 is the introduction of an on-linespell check program. The system is presented as a webservice, butthe feature has some errors that need workarounds to function properly.Spell Check is a default component of Microsoft Office SharePointServer (MOSS) but is not available in Windows SharePoint Services(WSS). The system is a welcome adaption and covers the supportedSharePoint Languages. It is effective for detecting orthography errorsand provides correction suggestions; however the downside is that itlacks a grammar and a thesaurus and the dictionaries cannot be modified.The default window of the corrector can be used in custom compo-nents inside SharePoint, as ASPX-pages, with the inclusion of a fewlines of code. Finally, although the dictionaries cannot be modified, itis possible resolve this inadequacy by creating a list of words to beexcluded from Spell Check control. •

Gustavo Velez

Gustavo Velez is a Manager in theSolutions Development departmentat Avanade Netherlands, a globalconsultancy company. He has manyyears experience developing Wind-ows and Office applications, andmore than six years of daily pro-gramming experience with Share-Point. The author's articles can befound in many of the leading trade

magazines in English, Dutch and Spanish. He is also pleased tobe Webmaster of http://www.gavd.net/servers, the only Spanish-language site dedicated to SharePoint. Spanish-language rea-ders may want to consult Velez's book, “Programación conSharePoint 2007”. His new book “Workflows and SharePoint:Going with the flow” has been published recently. Velez has beenawarded MVP status in the area of SharePoint MOSS.

Noteren in agenda: 19 & 20 oktober a.s.SDN Conference

Advertentie Aladdin

Page 42: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

.NETC# Bert Dingemans

Extra controlsIn het vorige artikel zijn we ingegaan op de basis webparts voor hetmuteren van gegevens in tabellen in onze database. Vaak willen weechter een aantal controls die een andere opmaak hebben en eenaantal bijzonder controls tonen. In ons voorbeeld maken we een web-part waarmee we gegevens van een organisatie tonen in een detail-view control en willen we daarnaast een treeview vullen metgekoppelde gegevens van deze organisatie. Hierbij maken we zoveelmogelijk gebruik van onze helper klassen. Deze klassen zorgen vooreen standaard afhandeling van gezamenlijke functionaliteit, die her-gebruik en stabielere code oplevert. In de eerste afbeelding is te zienhoe dit webpart eruit ziet voor de gebruiker.

Fun met Webparts in ASP.Net - Deel 2

User Controls en WebpartsInleidingWebparts zijn een nieuw soort besturingselementen in webapplicaties geïntroduceerd door Microsoft in ASP.Netversie 2.0. Webparts zijn vooral bekend vanwege de toepassing binnen Sharepoint en MOSS. In deze twee plat-formen zijn webparts één van de mogelijkheden om eenvoudig toegang te krijgen tot legacy systemen. Maar ookin maatwerk ASP.Net applicaties zijn webparts “fun”. In een moderne webtoepassing is het meer en meer gebruikelijk dat gebruikers zelf een indeling kunnen maken van hun “eigen pagina”. Kijk naar sites als hyves.nl ende verschillende elementen lijken verdacht veel op webparts. Dit artikel is een tweede deel in een serie artikelenover webparts. In het eerste deel zijn we ingegaan op de basisfunctionaliteit. In dit artikel zullen we ingaan op hetwerken met user controls binnen webparts, de wizard control en het gebruik van helper classes bij specifieke web-parts. De webparts zijn ontwikkeld in C#. Dat is voor mij niet mijn dagelijkse programmeertaal (Vulcan.Net enVB.Net). Reden om hiervoor te kiezen is het feit dat de Sharepoint installatie van webparts die niet geschreven zijnin C# lastig is. De webparts zijn op deze wijze in een handomdraai geschikt te maken voor Sharepoint.

De control bestaat uit een zoek- en een keuze-dialoog. Na zoekenwordt de keuzelijst gevuld, wordt hier een waarde gekozen en danworden de detailview en de treeview gevuld.Onderstaande code toont hoe in het CreateControls-event een aan-tal specifieke controls aangemaakt worden. Er is hierbij gekozen voorde opzet van de controlfactory om het creëren van controls op eencentrale plaats te houden.

ControlFactoryHelper.CreateTextBox(this.Controls,

"zoeknaam", "", 500);

this.organisatie_id =

ControlFactoryHelper.CreateDropDownList(

this.Controls, "organisatie_id", "", 400);

this.relaties = ControlFactoryHelper.CreateTreeview(

this.Controls, "relaties", "Associaties");

this.detail = ControlFactoryHelper.CreateDetailsview(

this.Controls, "detail", "Detail");

Zijn de controls binnen het webpart beschikbaar, dan kunnen de treeview en de detailview gevuld worden nadat er op de knop kiezengeklikt is. In onderstaande code wordt de functionaliteit getoond.

protected void verwerk_kiezen(Object sender, EventArgs e){NameValueCollection para = new NameValueCollection();String sql = "";DRGHelper objHelper = new DRGHelper();para = ControlFactoryHelper.Controls2Collection(this.Controls);

this.relaties.Nodes.Clear();sql = "SELECT CONTACTPERSOON.contactpersoon_id,CONTACTPERSOON.voornaam & ' '& CONTACTPERSOON.achternaamFROM CONTACTPERSOONWHERE organisatie_id = #organisatie_id#";

objHelper.Statement2TreeView(sql,this.relaties, "Contactpersonen", para);sql = "SELECT project_id, project_naam

Ook in maatwerk ASP.Net applicatieszijn webparts “fun”

MAGAZINE42

Page 43: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

.NETC#

FROM PROJECT, CONTACTPERSOON WHERE PROJECT.contactpersoon_id =

CONTACTPERSOON.contactpersoon_id AND CONTACTPERSOON.organisatie_id =

#organisatie_id#";objHelper.Statement2TreeView(sql, this.relaties,

"Projecten", para);

sql ="SELECT * FROM ORGANISATIEWHERE organisatie_id = #organisatie_id# ";

objHelper.Statement2DetailsView(sql, this.detail, "Overzicht", para);

}

Duidelijk te zien is hoe de helper klasse ons behulpzaam is bij het inkapselen van functies die voor hergebruik in aanmerking komen. Alsvoorbeeld in onderstaande code wordt een treeview gevuld op basisvan een SQL-statement.

public void Statement2TreeView(

string sql, TreeView tree,

string naam, NameValueCollection colPara)

{

DataSet ds;

TreeNode kind;

sql = this.verwerkParameters(sql, colPara);

ds = Statement2DataSet(sql);

if (ds.Tables.Count > 0)

{

kind = new TreeNode(naam);

foreach (DataRow row in ds.Tables[0].Rows)

{

kind.ChildNodes.Add(

new TreeNode(row[1].ToString(),

row[0].ToString()));

}

tree.Nodes.Add(kind);

}

}

Allereerst wordt een dataset aangemaakt op basis van het SQL-state-ment en vervolgens wordt iedere datarow toegevoegd aan de tree -view. Hierbij is een aanname gedaan dat het select-statement slechtstwee kolommen in de resultset heeft. Bij uitbreidingen van de library zalhier waarschijnlijk met parameters gewerkt gaan worden die een enander afhandelen op een meer generieke wijze.

User controlsIn ASP.Net kunnen user controls ontwikkeld worden. Deze user controls gaan dan fungeren als een container object voor meerderebesturingselementen. Eigenlijk is een webpart niets anders dan eenuser control waar een aantal extra eigenschappen aan is toegevoegd;met name de koppeling met de webpart-manager en de zones zijnwebpart specifiek.

In ons voorbeeld zullen we een besturingselement implementeren datnet als de webparts een aantal aardige extra’s biedt, namelijk de wizard control. Deze control maakt het mogelijk om de gebruiker mid-dels een aantal stappen door een complex werkproces te begeleiden.

In ons voorbeeld zullen we medewerkers aan een project koppelen. Dit proces bestaat uit een aantal stappen waarbij als laatste stap projecten en medewerkers aan elkaar gekoppeld worden. In onder-staande afbeelding wordt het werkproces weergegeven.

We hebben het onszelf iets moeilijker gemaakt doordat we, als we direct op project willen zoeken, een stap moeten overslaan; in het andere geval willen we dat alleen de projecten van een organisatie getoond worden.

Zodra een webpart in een ASCX-file wordt geplaatst wordt het mo-gelijk om een groot aantal eigenschappen in te stellen via Visual Stu-dio. In onderstaand codevoorbeeld zijn de belangrijksteeigenschappen opgenomen voor de wizard. Door de hoeveelheid aaneigenschappen is het mogelijk om de wizard echt helemaal naar eigeninzicht te configureren.

<asp:Wizard ID="Wizard1"

runat="server"

StepNextButtonText="Volgende"

StartNextButtonText="Volgende"

StepPreviousButtonText="Vorige"

CancelButtonText="Annuleren"

DisplaySideBar="True"

FinishCompleteButtonText="Voltooien"

FinishPreviousButtonText="Vorige"

OnNextButtonClick="Wizard1_NextButtonClick"

ActiveStepIndex="0"

Style="margin-left: 0px"

OnFinishButtonClick="Wizard1_FinishButtonClick">

<WizardSteps>

De elementen zijn waarschijnlijk duidelijk, maar toch een korte toelichting:• De Click events zijn ingesteld om een functie aan te roepen die voor

de verdere afhandeling zorgt;• DisplaySideBar is een aardige eigenschap die het mogelijk maakt

om de gebruiker te tonen waar hij of zij zich in het wizard proces be-vindt. In de afbeelding op pagina 45 een voorbeeld;

• ActiveStepIndex geeft aan bij welke pagina men dient te beginnen(PS: Kan iemand verzinnen waarom je niet bij de eerste pagina wiltbeginnen??)

Binnen de wizard worden vervolgens de pagina’s gedefinieerd in devorm van wizard-steps. Binnen deze wizard-steps kunnen eenvoudigde gewenste controls geplaatst worden. In het codevoorbeeld hieronder is één wizard-pagina getoond in ASP.NET code.

Eigenlijk is een webpart niets andersdan een user control

magazine voor software development 43

Page 44: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

<asp:WizardStep ID="Zoeken_Organisatie_Project" runat="server" Title="Zoeken op Organisatie of Project"><table><tr><td align="left">Zoeken naar*</td></tr><tr><td align="left"><asp:XmlDataSourceID="DlaDataSourceOrganisatie_Project"runat="server"><Data>

<keuzelijst><lijst optie="Organisatie" /> <lijst optie="Project" />

</keuzelijst></Data>

</asp:XmlDataSource><asp:RadioButtonList ID="Organisatie_Project"

DataTextField="optie" DataValueField="optie"DataSourceID="DlaDataSourceOrganisatie_Project" runat="server" RepeatDirection="Horizontal">

</asp:RadioButtonList><asp:RequiredFieldValidator

ID="Valideer_Organisatie_Project" runat="server"ErrorMessage="Organisatie Project keuze"ControlToValidate="Organisatie_Project"Display="None">

</asp:RequiredFieldValidator></td></tr><tr><td align="left">Zoek naar</td></tr><tr><td align="left"><asp:TextBox ID="ZoekNaar" runat="server"Style="height: 20px; width: 180px; text-align: left;"TextMode="SingleLine">

</asp:TextBox><asp:RequiredFieldValidator ID="RequiredZoekNaar"

runat="server" ControlToValidate="ZoekNaar"Display="None" ErrorMessage="Zoek naar is verplicht">

</asp:RequiredFieldValidator></td></tr><tr><td align="center"><asp:ValidationSummary ID="ValidationSummary4" runat="server" ShowMessageBox="TRUE" ShowSummary="FALSE" />

</td></tr></table>

</asp:WizardStep>

Zoals te zien is zijn niet alleen controls binnen een wizard-step te plaat-sen maar ook allerlei opmaakelementen. In dit voorbeeld is een tabelopgenomen die ervoor zorgt dat de elementen binnen een paginamooi uitlijnen. Daarnaast kunnen extra controls toegevoegd worden,zoals de validatie-controls van ASP.Net.

In de workflow hebben we ons ten doel gesteld dat als er voor eenproject gekozen wordt de vraag omtrent de organisatie wordt over-geslagen. Dit dient in de programmacode van de control afgehandeldte worden. Onderstaande code toont hoe dit geïmplementeerd wordtin het event voor de Volgende-button in de wizard.

protected void Wizard1_NextButtonClick(object sender,WizardNavigationEventArgs e){NameValueCollection para = new NameValueCollection();DRGHelper objHelper;

objHelper = new DRGHelper();switch( e.CurrentStepIndex ){case 0:if(this.Organisatie_Project.Text == "Organisatie"){Wizard1.ActiveStepIndex = 1;para.Add("organisatie_naam", this.ZoekNaar.Text);objHelper.Sql2ListControl("SELECT organisatie_id as valuecolumn,

organisatie_naam as displaycolumn FROM ORGANISATIE WHERE organisatie_naam LIKE '%#organisatie_naam#%' ORDER BY 2",

organisatie_id, "valuecolumn", "displaycolumn", para);}else

{Wizard1.ActiveStepIndex = 2;para.Add("project_naam", this.ZoekNaar.Text);objHelper.Sql2ListControl("SELECT project_id as valuecolumn,

project_naam as displaycolumn FROM [PROJECT] WHERE project_naam LIKE '%#project_naam#%' ORDER BY 2", project_id, "valuecolumn", "displaycolumn", para);

}break;

In het event is op te vragen in welke stap van de wizard we zitten. Isdit de eerste stap, dan kunnen we opvragen of de gebruiker heeft ge-kozen voor organisatie of project. In het eerste geval wordt de keuze-lijst voor organisaties gevuld en getoond, in het andere geval wordtde project-keuzelijst gevuld. Opvallend is hierbij dat door het instellenvan de activestepindex bepaald kan worden of een pagina moet wor-den overgeslagen. In het geval van de projectkeuze is namelijk de stapmet de organisatie gegevens niet meer relevant.Op de laatste pagina van de wizard verschijnt de Voltooien-knop. Dezeknop zal een aantal bewerkingen uit moeten voeren op onze data-base. Hierbij zijn onze helper-klasses weer relevant. In de onder-staande code een voorbeeld van deze verwerking; in devoorbeeldtoepassing is de gehele code voor deze wizard control tevinden.

protected void Wizard1_FinishButtonClick(object sender,

WizardNavigationEventArgs e)

{

DRGHelper objHelper = new DRGHelper();

NameValueCollection para = new NameValueCollection();

String sql =

"INSERT INTO [Medewerker_Project]

(medewerker_id, project_id, uur_tarief, begin_datum,

eind_datum)

VALUES

(#medewerker_id#, #project_id#, '#uur_tarief#',

##begin_datum##, ##eind_datum##)";

for (int i = 0; i < medewerker_id.Items.Count; i++)

{

if (medewerker_id.Items[i].Selected)

{

.NETC#

MAGAZINE44

Page 45: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE

para.Clear();

para.Add("project_id", project_id.Text);

para.Add("uur_tarief", uur_tarief.Text);

para.Add("begin_datum", begin_datum.Text);

para.Add("eind_datum", eind_datum.Text);

para.Add("medewerker_id",

medewerker_id.Items[i].Value);

if (objHelper.Statement2Database(

objHelper.ProcessStatement(sql, para)) == false)

{

error.Text += objHelper.errorMelding;

};

}

}

}

Door gebruik te maken van de helper-klasse wordt het eenvoudig mogelijk om een collectie met naam/waarde combinaties te vullen envervolgens een SQL-statement naar de database te sturen op eenstandaard manier op basis van de helper-klasse.

SamenvattingIn dit artikel is ingegaan op een aantal extra mogelijkheden van webparts. Webparts zijn niet alleen te gebruiken voor standaard controls, ook eigen combinaties binnen een webpart zijn eenvoudigmogelijk. Door de opzet van onze helper-klassen kunnen we eenvoudig eigen opmaak gebruiken en toch gebruik blijven makenvan standaard functies in onze helper-klassen.Daarnaast is het binnen webparts goed mogelijk om user controls tedefiniëren. Dit biedt extra mogelijkheden om de opmaak en volgordevan controls binnen de webpart helemaal naar eigen inzicht in te richten. In dit artikel hebben we als voorbeeld een wizard ontwikkeld bestaande uit een aantal stappen. Bij dit artikel hoort een

Bert Dingemans

Bert is als software architect werk-zaam binnen het maatschap FreeIT,een maatschap van ICT professio-nals. Bert heeft een voorliefde voorModel Driven Development en hetgenereren van software. Zo heeft hijCASE tools ontwikkeld in Visual Objects als DLArchitect en DLAWork in Process. Er zijn freeware

versies van deze tools beschikbaar op de dla-os website. Bertheeft een weblog op www.dla-os.nl.

.NETC#

voorbeeldtoepassing met een uitwerking van bovengenoemde con-trols. Zie de SDN-website of de website www.dla-os.nl (onder artike-len) voor deze source-code. •

UX TIP:Silverlight Tips of the Day

Mike Snow is een senior SDET Lead bij het Web Tools Teamvan Microsoft en houdt zich onder andere bezig met Silverlighttools. Op zijn blog plaatst hij regelmatig “Tips of the Day” overSilverlight en gaming die je kunnen helpen bij het game programmeren. Het Blog is te vinden op http://silverlight.net/blogs/msnow/.

Advertentie Sybase / iAnywhere

Page 46: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

DELPHI Cary Jensen

Introduction to Language IntegratedQuery with Delphi Prism: Part 1

Turning our attention to the general case of LINQ, LINQ queries canbe divided into three basic parts. These are:

• A queryable source of data• A query definition• Query execution

The following sections describe each of these parts in greater detail.The code samples shown, and the example Delphi Prism project thatappears in the accompanying screenshots, is called LINQExamples,and can be downloaded from the SDN-site through the online versionof this article.

Queryable Sources of DataIn strictly .NET terms, a queryable source of data is any object thatimplements the generic IEnumerable<T> interface, which includesList<T> and Dictionary<TKey, TValue>. In Delphi Prism, this also includes any collection that is declared as a sequence, as well as arrays (both fixed and dynamic).Some of the LINQ technologies, such as LINQ to DataSet and LINQto XML, are implemented through LINQ providers, which are supportclasses that enable LINQ operations. These providers usually includespecial methods that provide access to an IEnumerable<T> referencebased on an object that otherwise does not support this interface. Forexample, LINQ to DataSet provides the AsEnumerable extension method to the DataTable class.

The following variable declaration defines a simple queryable datasource. In this case, the data source is a sequence.

var seq: sequence of Integer := [1,2,3,4,5,6,7,8,9];

Query Definitions using Query SyntaxA query definition consists of two parts, a query variable and a queryexpression. Furthermore, query expressions are defined using one oftwo techniques. The first is called query syntax, and the second iscalled method syntax. This section describes query syntax. Methodsyntax is described later in this article.

Query expressions are defined using a combination of one or moreLINQ statements, comparison operators, extension methods, andvalue references. At a minimum, a LINQ query includes a ‘from’-clause, which defines an alias and a data source. Consider the follo-wing code segment:

var numbers: sequence of Integer := [1,2,3,4,5,6,7,8,9];

var myquery := from c in numbers select c;

The first line of code defines the data source, and the second line defines the query. The query in this case selects all items from the sequence numbers, as can be seen in the following figure (the codethat populates the list box has not been shown yet).

Language Integrated Query, or LINQ (pro-

nounced link), is a declarative programming

language developed by Microsoft for the .NET

framework. In a declarative programming

language you specify what result you want to

achieve without needing to specify how those

results are produced.

SQL SELECT statements are an example of

declarative programming. With a given SQL

statement you specify what data you want re-

turned. It is up to the SQL engine to determine

how that data is derived.

Traditional Delphi, on the other hand, is categorized as imperative programming. When writing Delphi code, you generally describe indetailed terms how you want the result obtained. You do this usingcontrol structures, expressions, and explicit calls to functions and procedures.This article is designed to provide you with a general overview of usingLINQ with Delphi Prism, the latest .NET development tool from Embarcadero Technologies and RemObjects. For a more detailed discussion of LINQ and its related topics, refer to the latest version ofthe .NET framework SDK.

Overview of LINQLanguage Integrated Query comes in a variety of different flavors, depending on the version of the .NET framework you are compilingagainst. For example, there is LINQ to Objects, LINQ to DataSets,LINQ to SQL, and LINQ to XML. Each of these technologies, whichwere introduced in .NET 3.0, provides classes you can use in conjunction with LINQ to work with objects in various domains of the.NET framework.

In addition, some of the major new features that are emerging in .NETalso are LINQ related. One example is LINQ to Entities, which is partof the Entity Framework. The Entity Framework is one of the latest database technologies being promoted by Microsoft.

With a given SQL statement you specify what data you want returned

MAGAZINE46

Page 47: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

expressions are discussed briefly later in this article). Finally, similar toSQL, LINQ queries can include subqueries.

Executing LINQ QueriesDefining a query and executing a query are two distinct steps (thoughas you will learn shortly, Delphi Prism provides a mechanism for combining these operations). Specifically, the query defined in the preceding section identifies what the query will do, but does not execute the query. In LINQ this is referred to as deferred execution.

You cause the query to be executed by iterating over it using a foreach loop. Each execution of the loop brings back another instanceof whatever the query returns. For example, if you used a for eachloop to iterate over the query shown in the preceding example, eachiteration of the loop would return a different instance of the anonymous type.

The following is the entire code sequence (short as it is), which showshow the Value members of the returned objects are assigned to the listbox (which is name ResultList in this example).

ResultsList.Items.Clear;

var numbers: sequence of Integer := [1,2,3,4,5,6,7,8,9];

var myquery :=

from c in numbers select new class(Value := c * c);

for each m in myquery do

ResultsList.Items.Add(m.Value.ToString);

When written to the list box, this query result looks like the following.

Fig. 2: Data from an anonymous type returns from a LINQ query

Similar to the alias in the query definition, the for each loop defines alocal variable that holds the value of the item that is returned in eachiteration. In the preceding code, this variable is named m. In mostcases, Delphi Prism uses type inference to determine the type of thisvariable (which is fortunate in this case, since we used an anonymoustype).

Fig. 1: The LINQExamples project

The ‘c’ in the preceding query is an alias, and it is used to referenceitems in the numbers sequence. The ‘select’-part of the query, whichcontrary to SQL standards, appears at the end of the statement, defines what is returned by the query. In this case, the query returnseach of the items in the sequence.

The preceding query really just creates another sequence that is no dif-ferent from the one that it queried. Most LINQ queries, by comparison,either select subsets of the data, perform data transformations, orother similar operations. The following query includes a ‘where’-clausethat limits the myquery sequence to those numbers between 4 and 8,inclusively. As you can see, the alias is essential for performing thisoperation.

var numbers: sequence of Integer := [1,2,3,4,5,6,7,8,9];

var myquery := from c in numbers where

(c >= 4) and (c <= 8) select c;

In both queries shown so far in this section, the select-clause couldhave been omitted. Specifically, if what we are returning is exactly thesame type of item as in the sequence, we can omit the select-clausealtogether. In other words, omitting the select clause is somewhat similar to a SELECT * clause in a SQL query. The following query,which does not have a select-clause, produces the same result as thepreceding one.

var numbers: sequence of Integer := [1,2,3,4,5,6,7,8,9];

var myquery := from c in numbers where

(c >= 4) and (c <= 8);

The select clause in LINQ is required when you are querying objectswith one or more members, and want to only return a subset of itsmembers, or want to return transformed data. For example, the follo-wing query returns a sequence of objects whose values are equal tothe square of the original values. The objects returned by the selectclause, in this case, are anonymous types. (An anonymous type of anobject is never explicitly declared, one of many advanced languagefeatures supported by Delphi Prism.)

var numbers: sequence of Integer := [1,2,3,4,5,6,7,8,9];

var myquery := from c in numbers

select new class(Value := c * c);

LINQ queries can be relatively complicated. In addition to the from,where, and select keywords shown here, Delphi Prism also supportsthe following LINQ operations: order by, group by, join, with, take, skip,reverse, and distinct. In addition, LINQ queries can make use oflambda expressions, both in the where and select parts (Lambda

Defining a query and executing aquery are two distinct steps (thoughas you will learn shortly, Delphi Prismprovides a mechanism for combiningthese operations)

DELPHI

magazine voor software development 47

Page 48: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

DELPHI

Not all LINQ queries use deferred execution. To cause the results of thequery to retrieve immediately, you can use either the IEnumerable me-thods ToList<TSource> or ToArray<TSource>. An example of this isshown in the following code.

var numbers: sequence of Integer := [1,2,3,4,5,6,7,8,9];

var MyResults: Array of Integer :=

(from c in numbers where (c >= 4)

and (c <= 8)).ToArray();

for each val in MyResults do

ResultsList.Items.Add(val.ToString);

Similarly, if you use any of the grouping operations, such Average,Count, First, and so forth, the query is executed immediately. This isdemonstrated in the following code.

var numbers: sequence of Integer := [1,2,3,4,5,6,7,8,9];

var MyResults: Double := (from c in numbers).Average();

MessageBox.Show(MyResults.ToString);

LINQ Query Method SyntaxAs mentioned earlier, LINQ query expressions can be defined usingboth query syntax and method syntax. Method syntax is implementedthrough extension methods on the System.Linq.Enumerable class,and corresponds roughly to the LINQ query syntax operators.

The truth is that when you use query syntax in your query expressions,the compiler converts these into method syntax. Another way to putthis is that any query that you can write using query syntax can alsobe defined using method syntax. Interestingly, the opposite is not true.Specifically, there are some queries that you must define using me-thod syntax, as there is no equivalent in query syntax.

Unlike in query syntax, there are no aliases in method syntax. Instead,the methods are called on your IEnumerable object directly, using dotnotation. These operations are typically performed in a single expres-sion. In other words, using dot notation, method syntax sometimesincludes a number of method calls, implemented through a chain ofcalls.

This is demonstrated in the following code segment, which producesa query identical to the first one listed in the preceding section “QueryDefinitions using Query Syntax.”

var myquery := numbers.where(c -> c >= 4).

where(c -> c <= 8).orderby(c -> c).select(c -> c);

NB: The preceding statement is a single statement, even though ithas been wrapped onto two lines due to the limits of the column spacein this article. Fortunately, this wrapped form can still be compiled byDelphi since its compiler is designed to ignore white space. Also, thearguments of the where, orderby, and select clauses are lambda expressions. Lambda expressions are discussed in the following section.

As with the query expressions, the select method call here is not necessary, since there is no transformation being performed on thereturned items.

The syntax is a little different when your sequence contains more complex data. This can be seen from the following code, which is themethod syntax version of the code segment described in the followingsection “LINQ to Objects.”

var Customers := GetCustomers;

var query := Customers.Where(Customer -> Customer.Age > 10).

Where(Customer -> Customer.Age < 40).

Where(Customer -> Customer.Active);

Lambda ExpressionsLambda expressions are anonymous functions that can accept zeroor more parameters, and typically return a value. The parameters ap-pear on the left-hand side of the lambda operator, and are enclosedin parentheses (unless there are zero or one parameters, in which casethe parentheses are optional).

The parameters, if present, are being followed by the lambda opera-tor, which is the -> character sequence in Delphi Prism (C# uses =>as the lambda operator). When reading a lambda expression aloud,the lambda operator is spoken “goes to.” As a result, the first expres-sion in the preceding query expression is read “customer goes to customer dot age greater than 10.”

The expression on the right-hand side of the lambda operator includes either an expression or a statement. This is the value that isreturned by the lambda expression (if the statement is an expressionlambda). It is possible, however, to include an expression block thatdoes not resolve to an expression. These lambdas are called state-ment lambdas. Statement lambdas should not be used in methodcalls when using method syntax.

In most cases, lambda expressions take advantage of the compiler’sability to infer the type of the input parameters.

SummaryThis article has provided you with a brief introduction to the composi-tion of language integrated queries. In part 2 of this article, numerousexamples of LINQ queries are shown, including technologies such asLINQ to Objects, LINQ to DataSets, and LINQ to XML. •

Lambda expressions are anonymousfunctions that can accept zero or moreparameters, and typically return a value

Cary Jensen

Cary Jensen is President of JensenData Systems, Inc., a training andconsulting company that won the2002 and 2003 Delphi InformantReaders Choice Awards for BestTraining. He is an award-winningauthor of 20 books, including Ad-

vantage Database Server: A Developers Guide (2007, Sybase),Building Kylix Applications (2001, Osborne/McGraw-Hill), JBuilderEssentials (1998, Osborne/ McGraw-Hill), and Delphi in Depth(1996, Osborne/McGraw-Hill). For information about onsite training or consulting services, you can contact Cary at [email protected] or visit his web site atwww.JensenDataSystems.com.

MAGAZINE48

Page 49: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

GENERAL

City planning and blueprintsThere is a lot of terminology in software development originating fromthis metaphor. Never heard an architect talking about the systemslandscape, or that architecture is like city planning? And where did youthink the term architecture itself originates from? Or the fact that we arebuilding software? And aren’t we still discussing software construc-tion and layered architectures? Did you know that in SAP projects pe-ople still refer to the design as a blueprint?At first sight this metaphor makes sense. However, what has worriedme about this metaphor over the past twenty years is that the creativepart ends after the design is delivered by the architect. No pretty sightfor developers eyes. In construction, this seems to be true. It’s themain reason construction is done by low educated workers againstequally low wages.

Ignoring creativityConverting this metaphor to software development, as a conse-quence, when the software architecture and design is done well, co-ding could be done elsewhere in the world by low educated peoplemuch cheaper than we are. This is where I highly dislike the con-struction metaphor. It considers coding as non-creative and repetitivework. It simply ignores creativity.Moreover, it also surpasses the fact that, as agile projects prove, thequality of software improves at high pace when there’s regular con-tact with the customer during development, much like the idea thatduring construction of your new house you regularly visit the con-struction site and pass comments to the contractor.So this is where it all comes down to: the idea that an architect sits athis desk and actually designs the software at his desk, after havingconsulted the customer. This is where creativity ends, and building thesoftware begins, according to plan.From this crippled metaphor traditional methodologists have fantasi-zed the living daylights out of us, poor developers. We were made tobelieve that software development is a craft rather than creative work.If the architecture is set out correctly and presented nicely, buildingthe software is low skilled, repetitive work. And hence, it can easily beoutsourced, off shored and done by low educated third world soft-ware developers. So if all this would be true, and construction is agood metaphor for software development, why is it not all projects aredelivered successfully, on-time, and on-budget?

Watching plumbersI’ll tell you why. Last week my new house was delivered by my con-tractor. Since then, all of a sudden I’m surrounded with lots of activityin and around the house. This activity falls in the fore mentioned cate-gory of low skilled, non-creative work. The house is crowded withplumbers, carpenters, friends with DIY capacities, gardeners. Some ofthem build closets, others construct my bathroom, whilst others layfloors or grass. And me? I’m constructing an attic in the garage with

a friend. When I was watching our plumbers reconstruct my bathroom,it occurred to me that after twenty years in this business, I finally sawthe light. Having opposed the house building metaphor for softwaredevelopment for so long, it’s time to see things through. Time for alittle re-construction. The plumbers in my bathroom, both in their earlyfifties actually quite enjoy their work, as I enjoyed constructing an atticin my garage. They were singing and making (lousy) jokes. Why is it, Iwondered, that these middle aged, low educated construction wor-kers whistle and make jokes during this work, that they’ve probablybeen doing since they left high school. Why?

I’ll tell you. It’s creative work. They try to make the water taps fit in thewall of my bathroom. It’s a puzzle. Drill bits and holes in my wall, fittingthe taps again. It’s even fun watching. It’s actually quite like I wouldaddress software development. Build it, try it out, test it, and possiblyrefactor the code. The plumbers actually work quite agile. During theprocess they ask me where I want the tap, where the shower shouldbe, or they propose suggestions on the tiling plan. Although the ba-throom isn’t finished yet, I’m quite sure it will work out fine.

Applying patternsAnd moreover, the plumbers work is bound by the bathroom archi-tecture we’ve laid out, and even more by patterns, just like developingsoftware is bound by software architecture and by design patterns.The plumbers know how high the shower regularly sits on the wall,how many centimeters they will have to drill in the wall to make thetap fit, just like I will use some implementation of a model-view-controller to implement the user interface, and domain driven designto construct the domain layer of my application. And you know what,to round up my argument, they make errors too, just like we softwaredevelopers do. And yes, they make repairs, like we do. It’s a bit like re-factoring. They try to create a solution, but if it doesn’t work, they’ll fixit, and try something else. Just like I would refactor my code, if itdoesn’t perform. But most of all, there’s one simple thing that binds ussoftware developers to gardeners, plumbers, and carpenters. Somuch for the construction metaphor. No doubt about it. Just like soft-ware construction. It’s creative work. Don’t let anybody ever tell youotherwise.

Sander Hoogendoornblog.sanderhoogendoorn.org •

For as long as I’ve been in this business, I’ve heard a lot of managers, architects andother non-coders compare software development to construction. In this metaphorthe architect creates the design and hands it over to the contractor, who does thework and the creative part ends with the architect handing over the design to the builders. Now doesn’t that sound like a software development project to you?

Interesting Things:Creative Plumbing

magazine voor software development 49

Page 50: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE

DATABASES

Bij het opslaan van de gegevens in de database zullen kolommen gedefinieerd moeten worden zonder dat zij ooit gevuld worden. Bij-komend probleem is dat bij een kleine wijziging in het objectmodel,dit doorgevoerd moet worden in het relationele model in de database.Een soortgelijk probleem doet zich voor bij de implementatie van condities in werkprocessen. Het implementeren van vertakkingen kenteen soortgelijk patroon.

Sinds SQL Server 2008 is het mogelijk om zgn. ‘sparse columns’ tedefiniëren. In dit artikel ga ik in op de mogelijkheden van deze functionaliteit voor object-relational mappings. Stapsgewijs geef ik uitbreidingen aan op de werkwijze in de vorm van SQL statements, tebeginnen bij inserts en updates en eindigend bij stored proceduresdie in één enkele stap een lijst van objectdefinities implementeren.Waar nodig wordt de resultaatset getoond bij een opdracht.

Sparse columnsSparse columns worden gedefinieerd voor gegevens in de databasedie niet altijd ingevuld worden (b.v. voor de vertakkingen zoals hierbo-ven beschreven). In onderstaand commando ziet u hoe een tabel metsparse columns gedefinieerd wordt en een tweetal statements:

CREATE TABLE [dbo].[Person](

[Id] [int] IDENTITY(1,1) NOT NULL,

[status] [varchar](50) NOT NULL,

[Name] [varchar](100)SPARSE NULL,

[Birthdate] [date] SPARSE NULL,

[Address] [varchar](50)SPARSE NULL,

[Place] [varchar](20)SPARSE NULL,

) ON [PRIMARY]

GO

UPDATE Person

SET Birthdate = GETDATE()-(45*365)

WHERE Id = 1;

SELECT *

FROM Person;

In het Create table statement worden de sparse columns gewoon gedefinieerd als de andere kolommen met een toevoeging van hettrefwoord sparse. Daarnaast moet de kolom gedefinieerd worden alsNULL wat logisch is omdat de gegevens gebaseerd zijn op een vertakking.

Vervolgens kunnen de gegevens in de sparse columns gewoon

Bert Dingemans

Sparse Columns inSQL Server 2008

Objectpersistentie eenvoudig gemaaktInleiding

Bij het toepassen van objectoriëntatie in een

ontwikkeltraject waarbij de domeinobjecten als

klasse geïmplementeerd worden, speelt het

probleem van object-relationele mappings.

Vooral het ophalen en wegschrijven van gege-

vens is lastig, omdat er steeds een vertaalslag

gemaakt moet worden van de representatie in

de database naar de representatie in de appli-

catie. Het wordt nog lastiger op het moment

dat men overerving gaat toepassen in de klas-

sestructuur. Een voorbeeld van het probleem

wordt gegeven in onderstaande afbeelding.

Fig. 1: Overerving in de klassestructuur

Het probleem dat hier ontstaat, is dat men bij het vertalen naar eentabel in een relationele database 6 kolommen nodig heeft terwijl er altijd slechts 4 ingevuld worden. Onderstaande tabel geeft een strokendiagram dat dit weergeeft. Sparse columns worden opgeslagen

als kolom van het type XMLObject Voornaam Achternaam Beroep Maandsal. Klantpas Krediet

1 Jan Jansen Ontwikkelaar 35002 Piet Van Dijk 400120 1200

50

Page 51: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

DATABASES

gewijzigd en opgevraagd worden met de standaard SQL comman-do’s. Dat laatste is bijzonder, want fysiek worden de gegevens van desparse columns helemaal niet in gewone kolommen opgeslagen maarin een kolom van het type XML. Dit maken we zichtbaar met de olgende twee commando’s.

CREATE TABLE [dbo].[Person](

[Id] [int] IDENTITY(1,1) NOT NULL,

[status] [varchar](50) NOT NULL,

[Name] [varchar](100)SPARSE NULL,

[Birthdate] [date] SPARSE NULL,

[Address] [varchar](50)SPARSE NULL,

[Place] [varchar](20)SPARSE NULL,

[AllXML] [xml] COLUMN_SET FOR ALL_SPARSE_COLUMNS NULL

) ON [PRIMARY];

GO

SELECT *

FROM Person

GO

Verrassend is nu dat de resultaatset er als volgt uitziet:

Het blijkt dat nu bij een * wildcard niet meer de sparse columns getoond worden maar alleen de fysieke kolommen. Verder is te zienhoe de sparse columns in een XML-kolom worden opgeslagen alseen XML-string. Wel is het mogelijk om de sparse columns te muteren en of op te vragen door ze op te nemen in de specificatie,zoals hieronder:

UPDATE Person

SET allxml = '<Name>Bert Dingemans</Name>

<Birthdate>1962-09-21</Birthdate>

<Address>Wildforster 37</Address>

<Place>Ede</Place>'

WHERE Id = 1

GO

SELECT Name, Address, Place, Birthdate

FROM Person

WHERE year(birthdate) < 1965

Het voorbeeld toont dat het mogelijk is om met een update statementde XML-kolom te muteren en vervolgens met de sparse columns degegevens op te vragen en omgekeerd. Dit biedt hele interessante mogelijkheden voor object persistentie en het werken met stored procedures zoals je zult zien in de volgende paragraaf.

Stored proceduresStored procedures in SQL Server hebben o.a. als voordeel dat zijmeerdere opdrachten tegelijkertijd op de database kunnen uitvoeren.Met name in onze situatie is dat wenselijk. In het voorbeeldscript iseen aantal voorbeeld stored procedures opgenomen. In dit artikel

lichten we er twee uit die laten zien dat SQL Server 2008 extra functionaliteiten biedt.

In de eerste stored procedure wordt als parameter een XML-string gebruikt om de nieuwe waarden van een rij te bewerken.

CREATE PROCEDURE [dbo].[Person_bewerken_XML](

@p_xml xml, @Id Int

)

AS

BEGIN

--exec Person_bewerken @xml = '#allxml', @Id=#id#

UPDATE [Person] SET [allxml] = @p_xml

, STATUS = 'Person_bewerken_xml'

WHERE id = @id

END

GO

De opzet is eenvoudig en bestaat uit een enkel statement dat de update uitvoert op basis van de primaire sleutel in de tabel; de statusis een extra kolom die aangeeft welke methode als laatste is uitge-voerd op het object. Dit gegeven is relevant in onze situatie van ob-jectpersistentie. Voordeel van het werken met een XML-string in plaatsvan met de afzonderlijke sparse columns is dat we ongestraft in onzeapplicatie elementen aan ons objectmodel kunnen toevoegen of mu-teren zonder dat dit gevolgen heeft voor de werking van onze storedprocedure. Ook als we de gegevens willen opvragen in de toepassingvoor het vullen van ons objectmodel, kunnen we dat opnieuw doen opbasis van de XML-kolom. Alleen bij rapportages en het bevragen vanons model voor specifieke objecten maken we gebruik van de sparsecolumns in de SELECT- of WHERE-component van een statement.

Nadeel van deze opzet is dat je nog steeds per object naar de data-base moet om een bewerking uit te voeren op de tabellen in de data-base. Sinds SQL Server 2008 is dat niet meer nodig, het is nu nl.mogelijk om met parameter-tables te werken. Dat is een soort para-meter-collection die je als read-only waarde kunt meegeven aan destored procedure. Hiertoe dient een type gedefinieerd te worden endeze moet voor de aanroep van de stored procedure gevuld wordenmet de gewenste waarden. In het codevoorbeeld zie je de definitie envervolgens 1 stored procedure aanroep die 3 rijen wijzigt in de tabel.

CREATE TYPE dla_parametertable

AS TABLE

(id int

, p_xml xml

, p_status varchar(50)

);

GO

CREATE PROCEDURE [dbo].[Person_aanmaken_valuepara](

@p_xml dla_parametertable readonly

)

AS

BEGIN

DELETE FROM [Person];

INSERT INTO [Person] ([allxml], status )

magazine voor software development 51

SQL Server 2008 kent parameter-tables

Id Status AllXML

1 Person_aanmaken <Name>Bert Dingemans</Name><Birthdate>1962-09-21</Birthdate><Address>Johanna Naberstraat 48</Address><Place>Culemborg</Place>

2 Person_aanmaken <Name>Anneke Hubert</Name><Birthdate>1965-10-15</Birthdate><Address>Johanna Naberstraat 48</Address><Place>Culemborg</Place>

3 Person_aanmaken <Name>Jeroen Dingemans</Name><Birthdate>1995-08-31</Birthdate><Address>Johanna Naberstraat 48</Address><Place>Culemborg</Place>

Name Address Place Birthdate

Bert Dingemans Wildforster 37 Ede 1962-09-21

Page 52: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

DATABASES

SELECT p_xml, p_status FROM @p_xml

END

GO

declare @table dla_parametertable;

insert into @table values (1, '<Name>Bert Dingemans</Name>

<Birthdate>1962-09-21</Birthdate>

<Address>Rhodosdreef 154</Address>

<Place>Utrecht</Place>', 'Person_aanmaken_para')

, (2, '<Name>Anneke Hubert</Name>

<Birthdate>1965-10-15</Birthdate>

<Address>Rhodosdreef 154</Address>

<Place>Utrecht</Place>', 'Person_aanmaken_para')

, (3, '<Name>Jeroen Dingemans</Name>

<Birthdate>1995-08-31</Birthdate>

<Address>Rhodosdreef 154</Address>

<Place>Utrecht</Place>', 'Person_aanmaken_para');

exec dbo.person_aanmaken_valuepara @table;

Het voordeel van deze werkwijze zal duidelijk zijn: aan de client-sidevan de toepassing wordt dit statement opgebouwd en vervolgens iser slechts 1 aanroep naar de database die vervolgens een refresh uitvoert op de objecten die meegegeven worden aan de stored procedure aanroep.

52 MAGAZINE

Bert Dingemans

Bert is als software architect werk-zaam binnen de maatschap FreeIT,een maatschap van ICT professio-nals. Bert heeft een voorliefde voorModel Driven Development en hetgenereren van software. Zo heeft hijCASE tools ontwikkeld in Visual Ob-jects als DLArchitect en DLA Workin Process. Er zijn freeware versies

van deze tools beschikbaar op de dla-os website. Bert heeft eenweblog op www.dla-os.nl.

Uitbreidingen van de werkwijze zijn natuurlijk denkbaar zoals het daadwerkelijk bijwerken van rijen in plaats van een delete en insert.Voorbeelden hiervan zijn te vinden op mijn website, waar ik werk aaneen Object Relational Mapper in Vulcan.Net.

SamenvattingMet de komst van SQL Server 2008 wordt een aantal nieuwe concepten geïntroduceerd die het mogelijk maken om op eenvoudigewijze Object Relational Mappers te introduceren. In het bijzondersparse columns, XML columns en parameter tables worden in dit artikel uitgewerkt en toegelicht. Bij dit artikel is een voorbeeldscriptopgenomen waarin extra voorbeelden zijn opgenomen en de sourcecode als compleet script is uitgewerkt. •

Advertentie 4DotNet

Page 53: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

GENERAL Freek Leemhuis en Maarten Metz

Kick Ass development - part 1: developing a developerDe halfwaarde tijd van (vooral technologische) kennis neemt steedssneller af. Technologische ontwikkelingen en globalisering zorgen ervoor dat je relatief veel moet doen om ‘bij te blijven’.Als beginnend programmeur heb je tijdens je studie misschien eenpaar honderd regels code geproduceerd. Als starter word je vervolgens aan het werk gezet in een omvangrijk software project,waarbij de complexiteit een veelvoud is van alles waar je tijdens je studie mee bent geconfronteerd. Gaandeweg kom je erachter hoecomplex software-ontwikkeling eigenlijk is. Je kennis en expertiseschieten vaak tekort om meteen een goede oplossing voor proble-men te kiezen. Misschien denk je “Wijsheid komt met de jaren, en alsik wat meer ervaring heb word ik vanzelf beter”. Dit is waar, maarslechts tot op zekere hoogte. Ervaring is nuttig, maar zegt echter niets over de kwaliteit die iemandkan leveren. Iemand kan jaren ervaring hebben met VB zonder zich tebekommeren om de basisprincipes van Object Oriëntatie. Als iemand5 jaar ervaring heeft met een bepaalde techniek, is hij of zij dan een expert? Of heeft iemand dan 5 keer een jaar dezelfde ervaring op verschillende projecten?

Misschien heb je wel eens samengewerkt met iemand die complexetaken fluitend uitvoert. Wanneer je hem of haar aan het werk ziet, lijkthet allemaal makkelijk. In no-time voegen dit soort types nieuwe talenen frameworks toe aan hun toch al indrukwekkende gereedschaps-kist. Misschien denk je dat dit soort personen meer talent hebben, endat jij nooit zo goed zult worden. In de meeste gevallen heb je het mis.

Een totaal gebrek aan talent kan het moeilijk maken om echt goed teworden op een bepaald gebied. Over het algemeen geldt echter datniet talent, maar focus, oefening en toewijding bepalende factoren zijnbij het ontwikkelen van deskundigheid. Mozart was op 4 jarige leeftijdal een muzikaal wonderkind, maar ook hij begon pas 13 jaar later muziek van wereldklasse te produceren.

Talent is dus geen voorwaarde om bij de besten te horen. Hard werken is dat wel. Geduld ook; in zijn boek ‘Talent is overrated’ betoogt Geoff Colvin dat om echt deskundig te worden, op welk terrein dan ook, meestal zo’n tien jaar gemoeid is.

Niet talent, maar de juiste combinatie van hard en effectief werkenkunnen enorme verbeteringen opleveren. Onderzoeken beweren datde productiefste ontwikkelaars vele malen productiever zijn dan deminst productieven. Voorzichtige inschattingen hebben het dan overeen factor 5, terwijl ook een factor van maar liefst 28 is aangetoond (zieo.a. ‘Code complete’ van McConnel en ‘Facts and Fallacies of Soft-ware Engineering’ van Glass). Stel je voor: een ontwikkelaar die 28webapplicaties oplevert in de tijd dat een andere ontwikkelaar er 1 op-levert! Voor je werkgever reden genoeg om deze raspaardjes te koes-teren – al zullen ze deze waarschijnlijk niet 28 keer zoveel betalen.

magazine voor software development 53

De Kick Ass DevelopmentReeksJe bent als software ontwikkelaar continu bezig om je

allerlei gereedschappen en technieken eigen te maken.De vaardigheid om snel en effectief te leren is misschienwel de belangrijkste die je als ontwikkelaar hebt. Het belangrijkste gereedschap dat je hierbij gebruikt is jebrein. Maar maak je daar wel optimaal gebruik van? Inde Kick Ass Development reeks zullen we je aan dehand van modellen en praktijkvoorbeelden inzichten entips geven om je brein te refactoren voor optimaal ren-dement. In het eerste deel zullen we vooral leerstijlen enleerhulpmiddelen behandelen. We zullen in verdere arti-kelen aandacht besteden aan kennisgebieden die voorsoftware ontwikkelaars interessant zijn. Bovendien zullen we adviseren hoe je het beste je brein in kunt zetten bij het oplossen van problemen.

“Greatness doesn’t come from DNAbut from practice and perseverancehoned over decades.” (Geoff Colvin)

Page 54: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE54

GENERAL

Leerstijlen en persoonlijkhedenDe meeste leertheorieën erkennen dat mensen verschillende leerstij-len hanteren. Je kunt bijvoorbeeld onderscheid maken in visuele ofauditieve leerstijlen. Sommige mensen vinden het prettig om te lerendoor te luisteren naar podcasts, terwijl anderen hierbij afhaken omdatze een visuele component missen.In het boek 'Experiential Learning: Experience As The Source Of Learning And Development' (1984) beschrijft Kolb een cyclus die gevolgd wordt bij leren (zie figuur 1).

Fig. 1: De leercirkel van Kolb

Als je iets meemaakt (concrete ervaring) is het belangrijk de ervaringente overdenken en te reflecteren over wat de ervaring betekent (reflec-tieve observatie). Vervolgens moet je deze losse overdenkingen in eentheorie integreren (abstracte conceptualisatie). Je kunt dan bedenkenhoe je deze theorie een volgende keer bij een soortgelijke gebeurte-nis toe kunt passen. Het toepassen van deze nieuwe inzichten (actiefexperimenteren) leidt dan weer tot nieuwe ervaringen. Onbewust leer je al op deze manier en doorloop je automatisch de 4fasen. Toch is het handig om daar bewust mee bezig te zijn zodat jehet proces kunt optimaliseren. Het is namelijk sterk afhankelijk van depersoon op welke fase van de cyclus de nadruk wordt gelegd. Kolbonderscheidt de volgende vier leerstijlen:

• Divergerend: de dromerJe bekijkt doorgaans dingen vanuit verschillende perspectieven. Jekiest er eerder voor om te kijken dan om meteen tot actie over tegaan en je gebruikt je verbeelding om tot oplossingen te komen. Jehebt een brede belangstelling, houdt ervan veel informatie te verzamelen en bent sociaal aangelegd.

• Assimilerend: de denkerJe hebt een voorkeur voor precieze, logische benaderingen. Jehoudt er van informatie te organiseren in overkoepelende concep-ten. Je leert vaak goed door duidelijke uitleg en achtergrond te krijgen, terwijl je aan praktische ervaring minder behoefte hebt. Jehanteert liever een meer academische benadering en bent mindergericht op je sociale omgeving.

• Convergerend: de beslisserJe bent goed in het toepassen van opgedane kennis om proble-men op te lossen. Je bent praktisch ingesteld en richt je meer optechniek dan op je sociale omgeving. Je bent zeer praktisch ingesteld en houdt van experimenteren.

• Accommoderend: de doenerIn accommoderende stijl ga je meer intuïtief te werk. Je maakt graaggebruik van analyses van anderen om hier in de praktijk mee te ex-perimenteren. Je bloeit op als er actie en initiatief wordt verlangden werkt graag in teams om doelgericht aan resultaten te werken.

In de software-industrie ben je vaak aangewezen op zelfstudie. Hethelpt dan om te weten wat je ‘standaard’ stijl is. Ben je bijvoorbeeldeen denker, dan ben je misschien geneigd een boek over design patterns van A tot Z door te lezen. Je hebt dan nog niet ervaren watnu eigenlijk de problemen zijn die deze patterns oplossen, en als je erniet actief mee experimenteert zul je het geleerde niet lang onthou-den. In dat geval zou je bijvoorbeeld een hands-on workshop kunnengebruiken om concrete ervaring op te doen.

Of stel dat je een framework wilt doorgronden. Je zou er boeken overkunnen lezen, of de complete API door kunnen werken. Een anderemogelijkheid is om het framework meteen toe te passen in een project en gaandeweg te leren wat de voor- en nadelen zijn (met allemogelijke refactoring vandien). Weer een andere mogelijkheid is omautomatische testen te schrijven en op het framework uit te proberen.Schrijf testen totdat alle gewenste functionaliteit getest is en je begrijpthoe het werkt. Wat je dan hebt is uitvoerbare documentatie op maat.Veel compacter en betrouwbaarder dan welke handleiding ook en alstestset ook uitvoerbaar op nieuwe versies van het framework waar-door je aan de falende testen meteen ziet welke functionaliteit veran-derd is. En terwijl je testen schrijft en uitvoert doe je daadwerkelijkeervaring op met het gebruik van het framework zonder de projectcode te vervuilen. Bovendien doorloop je alle fasen van hetmodel van Kolb.

Weet dus wat je eigen leerstijl is, en zorg dat je ook voldoende aandacht geeft aan de fasen die bij die stijl minder aan bod komen.

Metacognitie: monitor je leerprocesMetacognitie kan helpen bij het volgen van een effectief leertraject.Hierbij zijn twee processen belangrijk: het monitoren van voortgangvan het leren, en het aanpassen van strategieën als de werkwijze niethet gewenste resultaat oplevert. Je leert dus, en tegelijkertijd monitorje de voortgang en stuurt eventueel bij als de gevolgde strategie niethet gewenste resultaat oplevert.Dit kan worden toegepast door doelen expliciet te maken en resul-taatgericht te werk te gaan, bijvoorbeeld door leerdoelen SMART temaken (zie einde artikel).Wanneer je specificeert wat de stappen zijn die je wilt maken, hoe jevoortgang meet, en wanneer je bepaalde doelen wilt bereiken, wordthet ook makkelijker om zelfregulatie toe te passen. Je kunt tijdens hetleertraject beslissen of de leermethode(n) die je hebt gehanteerd effectief zijn of niet.

Zet je brein in de turbo stand

Toen de X286 PC uitkwam was deze veel sneller dan de eerdere IBMmachines. Dit nieuwe type computer had een turbo knop die de PCsneller maakte. Veel mensen vroegen zich af waarom die knop er zat- waarom zou je die knop niet altijd op ‘aan’ zetten? (bepaalde ouderesoftware was alleen geschikt voor langzame PC’s en werkte daarom alleen als de knop op ‘uit’ stond). Omdat gebruikers niet precies wisten waar de knop voor diende stond deze vaak uit waardoor demachine niet optimaal presteerde. Ons brein heeft verschillende niveaus van activiteit, en verschillende situaties of benaderingen kunnen ervoor zorgen dat ons brein in eenvergelijkbare turbostand schiet.

Weet dus wat je eigen leerstijl is

Page 55: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

magazine voor software development 55

Ter illustratie het volgende waargebeurde verhaal:

“Een kennis paste enkele jaren geleden software voor een fabrieks-besturing aan, laadde de code naar de PLC (programmable logic controller ), activeerde het nieuwe programma en merkte tot zijn schrikdat het vrijwel direct muisstil werd in de fabriekshal om hem heen. Allefabrieksgeluiden van pompen, motoren en centrifuges waren plotse-ling gedoofd. De stilte duurde niet lang. Al snel kwamen operators debesturingsruimte in rennen en vroegen wat er gebeurd was. Wat bleek:hij had in de code een verwijzing gemaakt naar een label dat niet be-stond. Een 'goto' naar een ongedefinieerde plek. De instructie had dePLC volledig laten crashen en alle outputs die aan de PLC hingen vielen terug naar hun veilige stand. Het schoonmaken van alle leidin-gen en machines, maar ook het productieverlies dat geleden werddoor deze vergissing kostte veel tijd en geld. Je kunt je voorstellen datzo’n gebeurtenis je brein in turbostand zet en dat je zo’n fout niet snelmeer zal maken.”

Dit is een extreem voorbeeld, maar voor alle leermomenten geldt datze meer effect hebben als ze een emotionele component bevatten. Je herinnert je iets beter wanneer het verrassend is, of uitdagend. Jeherinnert je niet hoe je over straat liep en er niets gebeurde. Je herin-nert je wel dat je over straat liep en er iets bijzonders gebeurde. Je neemt heel veel waar terwijl je over straat loopt, maar slaat niet allesop. De opslagcapaciteit van je brein is beperkt en daarom ben je zeergoed uitgerust om alles wat niet belangrijk is te negeren. Er moet dusiets gebeuren, iets wat tegen de verwachting van je brein ingaat, omte zorgen dat het gebeurde opgeslagen en onthouden wordt.Je wilt bijvoorbeeld een nieuwe programmeertaal onder de knie krijgen, maar hebt er in het dagelijkse werk (nog) niet mee te maken.In de avonduren op de zolderkamertje buig je maar weer eens over dataangeschafte boek. Vaak is de stof droog, en is het moeilijk om je aandacht er bij te houden. Hoe kun je het brein, dat zo goed is in hetnegeren van onbelangrijke dingen, overtuigen dat de stof belangrijkis?

Ten eerste kun je de omgeving waarin je leert wijzigen: in plaats vanop je zolderkamertje weg te kwijnen kun je ook proberen om met vrien-den of collega’s samen een studiegroep op te zetten. In de developercommunity worden vaak veel activiteiten georganiseerd zoals SpecialInterest Group(SIG) meetings, code camps en coding dojos. Deze activiteiten bieden je de mogelijkheid om samen met anderen te experimenteren met nieuwe technieken. Je moet hiervoor vaak welmeer uit je ‘comfort zone’ treden, en dat kan best moeilijk zijn. Als jedie stap maakt zul je echter merken dat je in dergelijke situaties veelmeer leert dan in je eentje. De situatie brengt allerlei emoties met zichmee. Je moet je verlegenheid misschien overwinnen, maar vaak is hetgezellig, soms uitdagend, maar in alle gevallen komt er veel meer emotie aan te pas dan op je zolderkamertje. En je brein zal – in deturbo stand – dingen beter onthouden.

Niet alle leermomenten zul je met anderen delen, dus wat kun je in diesituaties doen om je brein toch in de turbo stand te krijgen?

Visualiseren is een uitstekende manier om meer delen van je brein teactiveren. Het maken van bijvoorbeeld een mindmap is hiervoor eenuitstekende manier. Gebruik hiervoor geen mindmap software, maargewoon papier en pen – de fysieke actie van tekenen gecombineerdmet het denken over de abstracties die je probeert weer te geven zorgtervoor dat je brein in de turbo stand zal schieten. Plaatjes zijn makke-lijker te onthouden dan woorden, en studies tonen aan dat kennis-overdracht in visuele vorm tot 89% effectiever is dan alleen tekst.

Doe wat je leuk vindt! Wanneer je bijvoorbeeld een muziekfanaatbent, maak dan een programma dat MP3tjes toont en afspeelt. Depositieve emotie van het bezig zijn met iets wat je boeit zal je stimule-

ren en je brein in de turbo stand zetten.Mocht je toch in je eentje door droge leerstof heen moeten worstelen,dan helpt de PQ4R methode (zie einde artikel) om het studiemateriaalbeter te onthouden.

Traditionele studieTraditionele studie zoals academische - of certificeringstrajecten leve-ren vooral declaratieve kennis (‘codified knowledge’) op: weten datiets zo is, ook wel feitenkennis genoemd. Om deze om te zetten naarprocedurele kennis (‘tacit knowledge’) is ervaring nodig. Om in pro-grammeertermen te spreken: de ervaring fungeert als de compiler diedeclaratieve kennis omzet in procedurele. Zoals ook het model vanKolb aantoont is alleen abstracte conceptualisatie niet afdoende. Datgezegd hebbende zijn er wel kenmerken aan te wijzen waar effectiefleermateriaal aan voldoet.

• Goede boeken zijn gecomprimeerde leerervaringen. Ze laten je zienwat belangrijke aandachtsgebieden zijn, en plaatsen kennis in eenrelevante context.

• Goede boeken laten ook zien hoe de kennis in praktijksituaties kanworden toegepast. Het gaat erom dat procedurele kennis uit depraktijk in principes worden gevat.

• Goede boeken laten je patronen zien die je zelf door ervaring al kent,maar die je nooit bewust herkende of verwoord had.

Iemand kan tientallen boeken lezen over design patterns zonder zezelf ooit toegepast te hebben. Alle patternkennis van zo'n persoon isdan declaratief. Het is niet ondenkbaar dat zo'n persoon met al dezedeclaratieve kennis op zak een leraar kan zijn voor iemand die zich wilverbeteren op het gebied van design patterns. Praktijkproblemen gaanvaak echter verder dan een ‘student registration system’ of een ‘ATM’waardoor zo’n leraar in de praktijk waarschijnlijk snel door de mandvalt.Bij traditionele studiemethoden wordt de procedurele kennis van deexpert omgezet naar declaratieve kennis (boeken/leerprogramma’s).Vervolgens moet de leerling deze declaratieve kennis door ervaringomzetten naar procedurele kennis. In figuur 2 wordt dat weergege-ven door de rode pijlen.

Fig. 2: Kennisoverdracht (vrij naar ‘Leidinggeven aan professionals?Niet doen!’ van Mathieu Weggeman)

Michael Polanyi zegt over procedurele kennis: “We know more than wecan tell” - het is voor experts vaak moeilijk om de procedurele kennisdie ze bezitten om te zetten naar een declaratieve vorm.Een illustratief voorbeeld hiervan is de ontwikkeling van een brood-bakmachine voor thuisgebruik door Matsushita. Bij de initiële ontwik-keling van dit apparaat kregen ze maar geen goed resultaat. Ze lietenten einde raad een engineer in dienst treden bij een meester brood-bakker om de geheimen van het bereiden te achterhalen. De engineer

GENERAL

Page 56: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE56

keek de kunst van het kneden af (het deeg werd gedraaid en uitge-rekt), en schreef al doende zijn bevindingen op. De broodbakker konzijn kunde niet goed onder woorden brengen, en er was iemand nodigdie de kunst afkeek om de kennis te om te zetten in declaratieve vorm.

Ook het proces van het omzetten van declaratieve kennis naar procedurele is moeizaam: er moet eerst ervaring worden opgedaan(en fouten worden gemaakt) voordat de kennis goed kan worden toe-gepast. Voor dit soort studietrajecten is de directe interactie tussenstudent en leraar (auteur) vaak miniem, en de student gebruikt éénvan de belangrijkste talenten van zijn brein niet: het vermogen te lerendoor imitatie.

Monkey see, monkey do!De mens heeft zich evolutionair gedurende vele eeuwen ontwikkelddoor te leren door imitatie, en ons brein is als gevolg daarvan heelgoed uitgerust om op deze manier te leren. Pas sinds we schrift gebruiken (en eigenlijk vooral sinds de uitvinding van de boekdruk-kunst) zijn we op grote schaal overgestapt naar bestudering van abstracte, declaratieve kennis. De methode waarvoor we het best zijnuitgerust wordt echter vaak verwaarloosd bij dit soort leertrajecten;het aantal 1 op 1 leermomenten, waarbij de expert direct in actie kanworden geobserveerd, is meestal beperkt.

In situaties waar dat wel gebeurt, kan er directe overdracht van procedurele kennis plaatsvinden. In figuur 2 is dat pad door de groenepijl aangegeven. De figuur maakt duidelijk dat het delen van kennis viade rode pijlen veel omslachtiger, langduriger en arbeidsintensiever isdan ‘onderlangs’ kennis te delen door te socialiseren. Juist voor hetdelen van snel verouderende kennis pleit Mathieu Weggeman in zijnboek ‘Leidinggeven aan professionals? Niet doen!’ voor socialiseren inmeester-gezel relaties. Voor basiskennis, die doorgaans een lage ontwikkelingssnelheid heeft, kan de lange weg zinvol zijn.

Technieken als pair programming en het uitvoeren van code reviewskunnen het aantal van dit soort overdrachtsmomenten vergroten. Ookde stroming die software engineering als een ambacht ziet (‘SoftwareCraftmanship’) promoot deze benadering door het vormen van mees-ter-gezel werkverhoudingen. De kenniskloof tussen leraar en leerlingmoet hierbij niet te groot zijn, omdat de kans bestaat dat de leerlingdan het grootste deel van de tijd geen idee heeft waarom de leraar dedingen doet die hij doet. ‘Learn to walk before you can run’.

Voor elk soort leerervaring geldt dat ze pas echt tot meesterschap leidtwanneer opgedane kennis ook daadwerkelijk in de praktijk kan worden gebracht. Idealiter kun je als software-ontwikkelaar op het kennisgebied van je interesse werk vinden. Mocht dit niet het gevalzijn, overweeg dan om via een hobbyproject en/of open source project ervaring op te doen om je declaratieve kennis te ‘compileren’tot procedurele kennis. Je zult het snelst leren als je kunt samenwer-ken met vakgenoten die net iets verder zijn dan jij. Of zoals RobertFripp, een zeer bekende jazz-gitarist, zijn leeradvies verwoordt: ‘zorgdat je de slechtste muzikant bent in een band’. Zorg dus waar mogelijk dat je samenwerkt met mensen die beter zijn dan jezelf.

Van beginner naar expertDe eerste stap in het opdoen van expertise is het bewust worden vanje eigen vaardigheid, of gebrek hieraan. Abraham Maslow schrijft een4-staps leerproces zoals weergegeven in het kader. Deze bewust-wording kan plaatsvinden als gevolg van zelfreflectie, maar bijvoor-beeld ook door een onafhankelijke meting (toets) of doorterugkoppeling van vakgenoten. Wees er wel op bedacht dat mensen de neiging hebben om hun eigen competentieniveau te over-schatten. Pas wanneer je hogere niveaus bereikt, begin je te beseffenhoeveel je eigenlijk niet weet. Als beginner op een kennisgebied moetje dan ook niet proberen meteen de hele context te begrijpen.

Wanneer je bijvoorbeeld met je auto een nieuwe route moet afleggen,en je bent niet bekend met de omgeving, dan zul je er voor kiezenblind op je navigatiesysteem of wegenkaart te vertrouwen. Echter, alsje de omgeving goed kent, en je kent de verkeersdrukte op bepaaldeknooppunten dan zul je hier en daar van de voorgestelde route afwijken. Om het optimale resultaat te bereiken (niet de kortste, maarde snelste route) neem je de context mee.

Als je al verschillende programmeertalen beheerst dan is een over-zicht van de syntax en belangrijkste features van een nieuwe taal vol-doende om de taal onder de knie te krijgen. De ervaring met andereprogrammeertalen geeft je voldoende context om snel inzicht te krij-gen in de nieuwe taal. Bij het leren van je eerste programmeertaal zulje eerst meer low-level moeten beginnen om uiteindelijk - door experimentatie en ervaring - te komen tot een high-level begrip.

TenslotteVoor ontwikkelaars is het noodzakelijk te blijven leren. Techniekenkomen en gaan, en het C# van vandaag is het COBOL van morgen.Het loont daarom om te leren hoe je moet leren. Metacognitie en deKolb leerstijlen bieden handvaten voor het optimaliseren van het leer-proces. Leren door imitatie gaat de mens zeer goed af, zorg daaromdat je zoveel mogelijk samenwerkt met mensen die meer expertisehebben dan jezelf. Houdt rekening met het tien jaar principe: je moeteen vak vaak vele jaren beoefenen voordat je echt een expert wordt.Talent is daarbij van ondergeschikt belang – oefening, toewijding enplezier zijn veel belangrijker.

Het SMART principeVolgens het SMART principe kun je doelstellingen expliciet en controleerbaar maken:• Specifiek - Het specificeren van een doel (wie, wat, waar, wanneer,

waarom) leidt tot een preciezere doelstelling waardoor het makke-lijker wordt er invulling aan te geven;

• Meetbaar - Specificeer hoe je vorderingen meet, en wanneer eendoel bereikt is;

• Acceptabel - Je kunt doelen hebben die in het begin onbereikbaarlijken. Vorm daarom doelen die wel binnen bereik liggen, waarna jemet kleine stappen richting het uiteindelijke doel beweegt;

• Realistisch - Is het doel haalbaar? Kost het niet te veel inspanning,of gaat het ten koste van andere dingen?

• Tijd gebonden – Specificeer wanneer je met de activiteiten begint,en wanneer je denkt klaar te zijn.

Beginners need unambiguous,context-free rules (Andy Hunt)

An investment in knowledge always pays the best interest. (Benjamin Franklin)

GENERAL

Page 57: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

De PQ4R methodeHeb je het gevoel dat dit allemaal te veel tijd kost? Misschien dat dezequote je motiveert: 'If you don't have time to do it right, when will youhave time to do it over?

Maslow's 4 stadia van lerenOnbewust bekwaam gedrag komt tot uiting in termen als ‘intuïtie’, ‘Fingerspitzengefühl’ en ‘gut feeling’. Deze termen verwijzen allemaalnaar het - vaak onbewust - toepassen van patroonherkenning waar-door een expert snel problemen kan doorgronden en een kwalitatiefgoede beslissing kan nemen.

magazine voor software development 57

Stadium Kenmerken

1 Onbewust onbekwaam

Je realiseert je niet dat je bekwaamheid tekort schietof dat je gedrag niet effectief is

2 Bewust onbekwaam

Je wordt je bewust van tekortkomingen en gaat actiefleren hoe het beter kan

3 Bewust bekwaam

Je past het nieuw aangeleerde bewust en met succestoe

4 Onbewust bekwaam

Het effectieve gedrag gaat automatisch, is vanzelf-sprekend

Maarten Metz

Maarten Metz werk als softwareontwikkelaar voor de Java compe-tence van Logica. Hij heeft 10 jaarwerkervaring in bit-, byte-, procedu-reel- en objectgeoriënteerde omge-vingen. Zijn interesses gaan uit naarsoftware design, - construction, -quality, - testing en de psychologievan software engineering. Hij leest

legio boeken en artikelen over voornoemde onderwerpen enhoopt ooit nog eens het software equivalent van Pink Floyd's'Dark side of the moon', Monet's 'Kathedraal van Rouen' en Tolstoj's 'Anna Karenina' te creëren.

Freek Leemhuis

Freek Leemhuis werkt als sinds1996 met het Microsoft develop-ment platform. Sinds 2006 werkt hijals consultant voor Logica in rollenals Developer en Software Architect.Hij heeft een bijzondere belangstel-ling voor onderwerpen als OO,Domain Driven Design, Agile tech-nieken en kwaliteit van software.

In zijn vrije tijd zoekt hij via Devnology (http://Devnology.nl) gelijk-gestemden om kennis en ervaring uit te wisselen. Volg zijn blogop http://freekleemhuis.com.

Preview - oriënteer jevooraf.

Door bijvoorbeeld eerst de inhoudsopgave door tenemen creëer je een context waarbinnen de speci-fieke deelgebieden kunnen worden geplaatst.

Questions - stel vra-gen

Stel zo veel mogelijk vragen over het onderwerpvoordat je gaat lezen.

Read - lees

Lees zorgvuldig en probeer antwoorden te vindenop de vragen die je gesteld hebt. De antwoordenleiden vaak weer tot nieuwe vragen waardoor eendieper niveau van tekstverwerking ontstaat.

Reflect - denk er overna

Probeer voorbeelden te bedenken en verbandente leggen met kennis die je al hebt of die je ooknog wilt opdoen.

Recite - vertel het inje eigen woorden

Nadat je een flink stuk gelezen hebt, probeer je ineigen bewoording voor te dragen wat je geleerdhebt. Als dit niet goed lukt, keer je weer terug naarde tekst en probeer je de gaten in je geheugen opte vullen.

Review - recapituleer

Nadat je het hoofdstuk gelezen hebt probeer je debelangrijkste punten terug te halen. Zorg ervoordat de vragen die je gesteld hebt allemaal naar te-vredenheid beantwoord zijn.

GENERAL

AGENDA2009

EKON, Mainz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5 - 9 oktober

Windows 7 launch voor Developers, Papendal, Arnhem, 19:00 uur . . . . . . . . . . . .19 oktober

SDN: Software Development Conference 2009, Papendal, Arnhem . . . .19 - 20 oktober

TechEd Developer EMEA 2009, Berlijn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 - 6 november

Microsoft PDC, Los Angeles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .17 - 20 november

SDN Magazine Nr. 103 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .20 november

SDN Event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14 december

Genoemde data onder voorbehoud

UX TIP:Silverlight Blog summary pageCheck out http://www.netvibes.com/rboarman#Silverlight

Page 58: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

.NETASP

Als je als ASP.NET ontwikkelaar nog niet naar AJAX hebt gekeken,dan wordt het hoog tijd dat je dat gaat doen. AJAX maakt de gebrui-kerservaring rijker en maakt het programmeren (vaak) makkelijker.Vooral als je gebruik maakt van alles wat er al op het web te vinden isom met AJAX te werken en dan met name van de ASP.NET AJAXControl Toolkit, waarvan in mei versie 3 uitgekomen is. De Control Tool-kit is een open source project dat vanuit Microsoft gestuurd wordt,maar waar in principe iedereen aan kan bijdragen of zelf aanpassingen kan doen. Je kunt de Control Toolkit in actie zien ophttp://www.asp.net/ajax/AjaxControlToolkit/Samples/ en daar kun jeook downloads, tutorials en video’s vinden. Omdat de Control Toolkitopen source is, kun je inspiratie opdoen voor je eigen controls en zienhoe je volgens best practices AJAX kunt gebruiken. En die best practices zijn nodig, want je kunt AJAX op allerlei manieren misbruiken.

Hoe het niet moet…ASP.NET AJAX bestaat eigenlijk uit een aantal onderdelen. Het be-langrijkste onderdeel is een JavaScript bibliotheek die het veel een-voudiger maakt om bepaalde functionaliteit te verzorgen in de browseren waarmee je web services kunt aanroepen op de server. Daarnaastis er een server deel voor het aanbieden van web services als onder-deel van een pagina en de UpdatePanel control. Die laatste lijkt heelhandig. Je kunt namelijk op een pagina regionen aanmaken die zichlos van de rest van de pagina kunnen verversen. Voor eenvoudige sce-nario’s waarbij bandbreedte en responstijd allemaal niet zo belangrijkzijn, is dit nog best handig, want je kunt er snel resultaat mee bereiken.Ook is het erg handig voor prototypes en demo’s, want man, wat looptdat lekker op een lokale machine! De koude douche komt als je com-plexe pagina’s met de UpdatePanel control hebt gemaakt en deze “inhet wild” gaat gebruiken. Dan blijkt het toch allemaal niet zo lekker telopen, want de UpdatePanel control is eigenlijk een heel dom ding.Wanneer een UpdatePanel ververst moet worden, wordt een volledigePostBack gedaan. Op de server wordt dan ook de volledige paginauitgevoerd alsof er sprake is van een PostBack. Daarna kijkt ASP.NETAJAX welke stukken van de pagina daadwerkelijk veranderd zijn enstuurt dat terug naar de browser, die daar de UpdatePanel control(s)bijwerkt. Heel vernuftig, maar een totaal verkeerde benadering, wantdit betekent enorm veel overhead in het netwerkverkeer en onnodigebelasting van de server.

Hoe het wel moetHet grote voordeel van AJAX is dat je web services aan kunt roependie op de server draaien en dat je het resultaat daarvan in de browserkunt verwerken. Wil je bijvoorbeeld een DropDownList vullen met gegevens aan de hand van de keuze uit een andere DropDownList,

dan kun je de betreffende gegevens ophalen met een webservice endan met wat JavaScript de DropDownList vullen. Dit werkt sneller enefficiënter dan een UpdatePanel waarin je de DropDownList zet die jewilt aanpassen. Ten eerste doe je geen volledige postback, maar gaanalleen die gegevens over de lijn die daadwerkelijk nodig zijn. Tentweede is de code om de DropDownList te vullen waarschijnlijk effi-ciënter. En ten derde kun je voor de verwerking van de data gebruikmaken van de kracht van de client computer. Het is natuurlijk wel watmeer werk om het zelf te doen, maar de voordelen maken het demoeite waard. Overigens hoef je voor dit voorbeeld niets zelf te doen,want de CascadingDropDown uit de Control Toolkit is specifiek gemaakt voor dit scenario.

Quick winsZonder dat je al erg diep in de technologie hoeft te duiken biedt deControl Toolkit een aantal controls die je heel snel kunt gebruiken endie al enorme voordelen bieden. De eerder genoemde Cascading-DropDown is daar een voorbeeld van, maar nog makkelijker en snel-ler zijn de verschillende “control extenders” waarmee je bestaandecontrols uit kunt breiden om bepaalde dingen te doen. Met de Pass-wordStrength control extender bijvoorbeeld kun je een TextBox uit-breiden om de sterkte van een wachtwoord te controleren. Dit kanvisueel op verschillende manieren. De FilteredTextBox en MaskedEditkun je aan een TextBox koppelen zodat gebruikers alleen bepaaldekarakters of een bepaald patroon (bijvoorbeeld een telefoonnummer)in kunnen voeren. In tegenstelling tot de ASP.NET validator controls,gaat dit proactief aangezien de gebruiker geen ongeldige invoer kangeven. Met een validator control kan dat wel, maar blokkeert de vali-dator de PostBack. Vanaf versie 3.0 bevat de Control Toolkit ook eenHTMLEditor control die je zou kunnen gebruiken als standaard inplaats van een van de commerciële controls die hiervoor beschikbaarzijn in de markt. Kortom, je doet er goed aan om snel eens te kijkennaar de Control Toolkit en er je voordeel mee te doen. Op naar snellere en intuïtieve webinterfaces!

Michiel van Otegem [email protected]

Ik woon in de buurt van Amsterdam en dat betekent wel haast automatisch dat Ajax mijn club is. Helaas heb ik de laatste jaren weinig reden om daar trots op te zijn. Toch ben ik een echte AJAX supporter, hoewel ik eerlijk moet zijn dat ik het dan niet meer over voetbal heb, maar over Asynchronous JavaScript And XML.

Michiel van Otegem

ASP.NET onder de Motorkap:Ben jij al AJAX Supporter?

AJAX zelf implementeren kost iets meerwerk, maar de voordelen maken het demoeite waard

MAGAZINE58

Page 59: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

ARCHITECTURE Marion Verwey en Nienke van de Brink

Hang je Project Vision ingelijst aan de muurIn veel projecten blijkt het Vision-document achteraf bezien een verspilling van tijd; niet omdat je het document niet nodig had, maaromdat je het vaak vergat te gebruiken. In het begin van het projectheb je veel aandacht aan het opstellen en afstemmen van het Vision-document met de klant besteed, maar daarna heb je de technischeuitwerkingen en beslissingen in het project niet meer genomen opbasis van de oorspronkelijk beschreven needs, maar op basis van deinschatting van een projectmedewerker.

Fig. 1: Zorg dat alle projectleden (de essentie van) het Vision-document kennen. Hoewel het misschien vreemd lijkt om een samenvatting van het Vision-document werkelijk aan de muur tehangen, kan dit in complexe projecten soms werkelijk helpen.

Wij vinden het belangrijk dat ieder teamlid het Vision-document kent.Het Vision-document beschrijft immers waarom het project gestart is(problem statement, needs) en welke functionele oplossing hiervoorgekozen is (features, functionele context). Het Vision-document bevatechter nog niet de gedetailleerde uitwerking van de oplossing in systeemrequirements (Use Cases en Supplementary Requirements).

Wanneer alle teamleden het waarom en wat van een project duidelijkvoor ogen hebben, voorkomt dit wantrouwen tussen business en IT –wantrouwen omdat de IT-er vindt dat de business niet duidelijk aan-geeft wat ze wil en de business vindt dat de IT-er altijd denkt in on-mogelijkheden in plaats van mogelijkheden. Door de IT-er deelgenootte maken van het probleem dat opgelost moet worden, kan hij ookproactief meedenken en aangeven wat een alternatieve oplossing kanzijn voor een slecht realiseerbare systeemrequirement.

Daarnaast helpt het Vision-document bij het snel bepalen van de oplossing bij wijzigingen doordat het Vision-document de needs enfeatures bevat en de bijbehorende stakeholders (zie ook de best practice over traceability) . Bovendien is het eenvoudiger om de scopevan het project te bewaken wanneer alle teamleden het Vision-docu-ment kennen. Iedereen weet wat de oorspronkelijk afgesproken scopeis, en waarom deze zo is bepaald. Onbewuste afwijkingen van descope vanwege onbekendheid met de doelstellingen van het projectkomen zo minder voor.

Fig. 2: Het-Vision document bevat zowel het waarom als het watvan een product en geeft daarmee een goed functioneel overzichtvan het project.

Betrek de juiste stakeholdersHet is belangrijk om je requirements samen met de juiste stakehol-ders te verzamelen en af te stemmen. Maar hoe bepaal je wie de juistestakeholders zijn? Je wilt niet met te veel zogenaamde stakeholdersom tafel zitten, want dan eindig je met Poolse landdagen waarbij geenbesluit genomen wordt. Je wilt echter ook niet aan het eind van je pro-ject ontdekken dat b.v. de beheerafdeling je product niet accepteert

magazine voor software development 59

Requirements Managementvoor Software ArchitectenInleiding

Veel projecten gaan, ondanks een enthousi-

aste start, nooit in productie. Herkenbaar?

Bij dergelijke projecten zijn vaak de require-

ments niet goed van kwaliteit, niet consistent

met elkaar of ontbreken volledig.

Tijdens het ontwikkelen van interne standaar-

den hebben wij uit onze ervaringen best prac-

tices gedestilleerd. In dit artikel delen we een

aantal van deze best practices. We kijken naar

de voordelen voor een project en geven hand-

vatten om deze best practices toe te passen.

Page 60: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE60

ARCHITECTURE

omdat het niet aan hun beheerrequirements voldoet. De juiste stake-holder is iemand die:• Direct geraakt wordt door de uitkomsten van het project, en daar-

bij ook in staat is de consequenties van de besluiten voor het eind-product te overzien;

• Besluitvaardig is en hierbij ook mandaat heeft om besluiten over defunctionaliteit van het product te nemen;

• Communicatief is (dus ook afstemt met zijn achterban) en mee wilwerken aan de ontwikkeling van dit product.

Wanneer je onvoldoende, of verkeerde, stakeholders bij je project betrekt zal dit er altijd toe leiden dat het product uiteindelijk niet geaccepteerd wordt. Betrek dus de juiste stakeholders, en leg de stakeholders en hun verantwoordelijkheden ook vast in het Vision-document.

SMARTificeer de requirementsMet het smartificeren van requirements bedoelen we het SMART opschrijven van de requirements. Hiermee voorkom je dat bijvoorbeeldde tester een requirement anders interpreteert dan de bouwer, die opzijn beurt weer een andere interpretatie heeft dan de functionaliteit diede requirements-specifier voor ogen had.

SMART staat voor Specifiek, Meetbaar, Accepteerbaar, Realiseer-baar/Realistisch, Tijdgebonden/Testbaar/Traceerbaar.Een voorbeeld van een niet functionele requirement die niet SMART is,luidt: “De performance van het systeem moet goed zijn.”Want wat is goed? De ene gebruiker vindt het al goed, als gegevensbinnen 5 seconden op het scherm staan, terwijl de andere gebruikerhet heel vervelend vindt als hij langer dan één seconde op een ant-woord moet wachten.Een SMARTere specificatie van deze requirement is: “Het tonen vangegevens op het scherm mag in 80% van de gevallen niet langer dan1,5 sec. duren.” Deze requirement is nu specifiek, omdat het spreekt over het tonenvan de gegevens op het scherm; meetbaar en testbaar omdat het in80% van de gevallen niet langer dan 1,5 seconde mag duren; accep-teerbaar omdat duidelijk is als meer dan 20% er langer dan 1,5 se-conde overdoet de requirement niet meer voldoet, en realiseerbaaromdat binnen de voor deze opdracht gebruikte technologieën dit eengangbare performance-eis is.

Bereik overeenstemming over de requirementsStakeholders vertegenwoordigen allemaal een andere doelgroep dushebben ze allemaal een ander beeld van het op te lossen probleem endaarom ook verschillende wensen voor de oplossing. Zorg dus dat jealle requirements met alle stakeholders afstemt en eventuele conflic-terende requirements aanpast, met ieders instemming. Een goedgoedkeuringsproces is hiervoor noodzakelijk. Ons advies hiervoor issimpel: gebruik workshops. Verzamel je requirements in een work-shop, zodat alle stakeholders elkaars requirements kennen en erken-nen, je de verwachtingen van al je stakeholders kunt managen en jeconflicterende requirements direct kunt benoemen en aanpassen –de eindgebruiker heeft hierbij in principe het laatste woord. Alle sta-keholders zijn met deze werkwijze volledig in de besluitvorming mee-genomen, waardoor toekomstige wijzigingen ook eenvoudigergeaccepteerd worden.

Naast acceptatie van je stakeholders moeten ook alle projectteamle-den de requirements begrijpen. Testers en designers zijn bovendienvaak kritische reviewers die vanuit hun rol goed de maakbaarheid enSMART-heid van requirements kunnen bevragen.Door het projectteam op tijd bij de review van de requirements te be-trekken voorkom je rework in een latere fase, zorg je voor een een-voudigere overdracht binnen het team en bereik je de optimaleoplossing voor de klant.

Testers en designers kunnen opmerkingen hebben die te maken heb-ben met de maakbaarheid en SMART-heid van requirements. Denkhierbij weer aan het voorbeeld van de performance van een systeem:“Het tonen van gegevens op het scherm mag in 80% van de gevallenniet langer dan 1,5 sec. duren.”

Zoals eerder beschreven kan dit een goede requirement zijn. Echter,in een complexe technische omgeving waarin het systeem verschil-lende services moet aanroepen, kan dit lastig realiseerbaar zijn. Dedesigner zal je hier dan ook op wijzen. De tester zal je bovendien vra-gen of er maxima gelden voor de overige 20%, en of het systeem eenfoutmelding moet tonen als het over deze maximumgrens heengaat.Na overleg met tester en designer kan deze requirement aangepastworden naar: “Het tonen van gegevens op het scherm mag in 80%van de gevallen niet langer dan 2 sec. duren. Wanneer het tonen vande gegevens langer dan 2 sec. duurt, moet de gebruiker een (beheerbare) foutmelding getoond worden.”

Daag je klant uit om niet alles als must have te classificerenAls je met de klant praat dan merk je al gauw dat hij eigenlijk alles wil.Ook de briljante ideeën die jij ze aan de hand doet willen ze graag heb-ben. Echter, als je alle requirements zonder prioritering of classificeringgaat uitvoeren, dan merk je in het algemeen dat het allemaal wel ergveel, lastig en duur wordt. Daarom is het ook in het belang van deklant, dat hij een onderscheid maakt tussen de ‘must haves’ en deander ‘haves’ in het MOSCOW-model (Must Have, Should Have,Could Have, Want to Have). Een manier om de klant uit te dagen omdit onderscheid te maken is door hem de vraag te stellen: “Wat gebeurt er als we dit niet in het systeem gaan ondersteunen?”

Ook bij het prioriteren is het belangrijk om de software-architect of designer erbij te betrekken. Door de klant feedback te geven over demaakbaarheid van een requirement maak je de klant duidelijk dat som-mige requirements erg duur zijn. Deze kosten-baten afweging maakthet voor de klant eenvoudiger om een requirement te ‘downgraden’.Het omgekeerde kan natuurlijk ook het geval zijn. Soms is een requi-rement voor een klant minder belangrijk, maar geeft de software architect aan dat het geen extra moeite kost om deze tegelijk met een‘must have’ requirement te realiseren. Door deze requirement dan direct te koppelen aan deze ‘must have’, kun je een voor het projectzo efficiënt mogelijke planning maken.

SMART staat voor Specifiek, Meetbaar,Accepteerbaar, Realiseerbaar/Realis-tisch, Tijdgebonden/Testbaar/Traceer-baar

“Wat gebeurt er als we dit niet in hetsysteem gaan ondersteunen?”

Testers en designers zijn bovendienvaak kritische reviewers die vanuit hun rol goed de maakbaarheid enSMART-heid van requirements kunnen bevragen

Page 61: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

magazine voor software development 61

ARCHITECTURE

Een voorbeeld van een requirement die door middel van het stellenvan de vraag “Wat gebeurt er als we dit niet in het systeem gaan ondersteunen?” van een ‘must have’ naar een ‘should have’ zou kun-nen verhuizen is de volgende: “Het systeem moet context-gevoeligehelpfunctionaliteit kunnen aanbieden.” Als je vervolgens de klant vraagt wat er gebeurt als er wel helpfunc-tionaliteit beschikbaar is, maar niet context gevoelig, dan antwoordt deklant vaak dat het op zich niet zoveel uitmaakt, maar dat de gebruikeralleen iets langer moet zoeken om de goede help-ondersteuning tevinden. In dit concrete voorbeeld verandert bij veel projecten deze‘must have’ vaak naar een ‘could have’ of ‘should have’. Daarnaastmoet je wel een nieuwe requirement toevoegen: “Het systeem moethelpfunctionaliteit aanbieden.”

Manage de verwachtingen, zowel van de klant als van jezelfNet als bij het Vision-document is verwachtingsmanagement een activiteit waar je vaak in de eerste fase van het project op focust omhet daarna te vergeten. Wat je je daarbij vaak niet realiseert, is dat eenproject een levende organisatie is, waarin bijna continu kleine wijzigingen aan de scope worden aangebracht. Wanneer je dezekleine wijzigingen niet duidelijk communiceert, zal het eindresultaatvaak een teleurstelling zijn voor de klant. Minstens net zo belangrijk ishet om ook je eigen verwachtingen te managen. Jij verwacht namelijkook iets van de klant, bijvoorbeeld medewerkers die een bijdrage aanhet project leveren, maar ook interface-specificaties of review-activiteiten. Wanneer je deze verwachtingen niet van te voren uitspreekt, zal de klant niet altijd aan jouw verwachtingen voldoen,waardoor het project vertraging kan oplopen.

Voor het managen van klantverwachtingen kun je bijvoorbeeld den-ken aan ons eerdere voorbeeld over de contextgevoelige helpfunctio-naliteit. Op het moment dat je besluit om dit terug te brengen tot een‘gewone’ helpfunctionaliteit moeten alle stakeholders op de hoogteworden gesteld. Als je dit nalaat, is het voor de gebruikers wel eenfikse teleurstelling op het moment dat het systeem in productie gaat.

Sta open voor wijzigingenWij komen regelmatig klanten tegen die huiverig zijn voor wijzigingenomdat ze bang zijn dat deze je project lastig bestuurbaar maken. Natuurlijk is de hoeveelheid wijzigingen een maat voor de stabiliteitvan je project, maar dit betekent niet dat je alle wijzigingen moet weren.Veranderingen gedurende het project zijn onvermijdbaar. Door dezewijzigingen te verwachten en een goed proces in te richten om dezete behandelen kun je je project ook met wijzigingen bestuurbaar houden. Stem het change-proces ook af met al je stakeholders, zodatiedereen weet hoe een wijziging behandeld wordt en wie daarovermag besluiten.

Een aantal aanbevelingen voor een goed change-proces zijn:• Zorg dat je expliciet vastlegt wat je met een wijziging doet (uitvoe-

ren, afwijzen of uitstellen);• Geef aan wanneer uitgestelde wijzigingen wel opgepakt worden;• Zorg dat de in de wijziging beschreven oplossing in lijn is met het

Vision-document; wijzigingen mogen alleen goedgekeurd wordenals deze bijdragen aan de needs die beschreven zijn in het Vision-document;

• Als de wijziging een functionele wijziging betreft, volg dan hetzelfdeafstemmingsproces als voor alle andere requirements, dus betrekalle relevante stakeholders;

• Zorg dat voor een wijziging niet alleen de code, maar ook de documentatie wordt bijgewerkt.

Een voorbeeld van een wijziging die goed doorgevoerd moet wordenis: “Gedurende de test wordt een fout gevonden, die te herleiden blijktte zijn tot een fout in de requirements.” Als gevolg hiervan moeten derequirements dus gewijzigd worden. Als je niet openstaat voor dezewijziging, betekent dit dat er uiteindelijk een foutief systeem wordt opgeleverd.

Gebruik de (kennis van de) software architectBij het opstellen van niet-functionele requirements is vaak ook gede-gen technische kennis nodig. Een requirement specifier heeft dezetechnische kennis vaak niet, maar de software architect natuurlijk wel.Hij kan je dan ook helpen bij het opstellen van goede en haalbare niet-functionele requirements.

Als voorbeeld van de bijdrage die de software architect kan leverenaan het opstellen van niet-functionele requirements, kun je weer denken aan het voorbeeld van de performance requirement: “Hettonen van gegevens op het scherm mag in 80% van de gevallen nietlanger dan 1,5 sec. duren.” Het is wel leuk als je opschrijft dat de gegevens altijd binnen 1,5 seconde op het scherm getoond worden,maar dit moet natuurlijk wel haalbaar zijn. De software architect kan indit geval heel goed aangeven wat binnen de gebruikte architectuurhaalbare performance-eisen zijn. Hij kan de grenzen zetten en vervol-gens kun je in overleg met de klant de uiteindelijke performance-eisenbepalen waardoor de uiteindelijke requirement er als volgt uit kan zien:“ Het tonen van gegevens op het scherm mag in 80% van de geval-len niet langer dan 1,5 sec. duren, wanneer geen externe services gebruikt worden en niet langer dan 2,5 sec. duren wanneer externeservices gebruikt worden.”

Traceer requirements … maar niet oneindigHet is belangrijk om requirements van hoog naar laag niveau traceer-baar te maken. Zo kun je detecteren of alle hoog niveau requirementsdaadwerkelijk verder uitgewerkt zijn. Met andere woorden: dekken derequirements de needs en features? Je wilt immers voorkomen datde klant om iets heeft gevraagd, maar dat je die high level require-ments niet hebt vertaald naar systeemrequirements (scope gap) of datje een leuke systeemrequirement hebt bedacht die geen aansluitingheeft op de bovenliggende requirements; hiervan heeft de klant daneerder aangegeven daar geen behoefte aan te hebben (scope creep).

Daarnaast kun je eenvoudig een impactanalyse voor een wijziging uitvoeren. Denk bijvoorbeeld aan een wijziging die later in het projectom technische redenen moet worden doorgevoerd. De bijbehorendedocumentatie moet ook op basis hiervan worden aangepast. Wanneer alle requirements van hoog naar laag getraceerd worden,kun je snel inzichtelijk maken welke documentatie aangepast moetworden. Wanneer je deze traces niet hebt aangebracht, moet je veeluitzoeken en is het risico groot dat je dit, omwille van de tijd, of gewoonomdat het saai werk is, niet meer doet. De documentatie die je danlater aan de beheerafdeling oplevert is niet meer in sync met het werkelijk ontwikkelde product, waardoor het werk voor de beheeraf-deling erg lastig wordt.

Hoe meer verschillende soorten requirements er zijn, des te meer mogelijkheden er zijn om de requirements te tracen, maar bedenk bijiedere vorm van tracing goed waarom je de tracing aanlegt en wat detoegevoegde waarde van de tracing is.

Veranderingen gedurende het projectzijn onvermijdbaar

Het is daarom heel belangrijk om bijhet begin van het traject te bepalenwat je gaat tracen en met behulp vanwelke tooling je dit ondersteunt

Page 62: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE62

ARCHITECTURE

Het nadeel van te veel tracen is dat het veel en saai werk is, waardoorook in de praktijk blijkt dat je deze traces niet goed onderhoudt. Hetnadeel van te weinig tracen is dat je onvoldoende profiteert van detoegevoegde waarde van tracing waardoor het werk de moeite nietwaard is.

Het is daarom heel belangrijk om bij het begin van het traject te bepalen wat je gaat tracen en met behulp van welke tooling je dit ondersteunt. Als je wel eens hebt geprobeerd meer dan 1000 requi-rements in Excel vast te leggen, dan weet je dat je dan het overzichtover alle requirements snel kwijt bent. Maar als je een uitgebreide requirements management tool gebruikt voor een klein project methonderd requirements levert juist dat veel overhead op en voldoetExcel prima.

We adviseren daarnaast ook om vanaf het begin van het project tra-ces vast te leggen; achteraf aanbrengen van tracing is veel en vooralook saai werk. In figuur 3 geven we een traceability model dat wij aanbevelen, met traces tussen alle requirements typen en naar de belangrijkste van requirements afgeleide deliverables.

Fig 3: Aanbevolen traceability model: dit model tracet alle require-mentstypen naar elkaar zonder hierbij in veel detail te gaan en legteen trace naar de belangrijkste van de requirements afgeleide technische en test deliverables

ConclusieHet opstellen van requirements is een lastig vakgebied en in de prak-tijk blijkt vaak dat je toch belangrijke zaken uit het oog verliest. In ditartikel hebben we vanuit onze praktijkervaringen een aantal best practices beschreven waarvan wij hebben gemerkt dat iedereen dezein de praktijk – bewust of onbewust – wel eens vergeet. Kort samen-gevat komen de best practices er op neer dat je vanaf het begin vanje project serieus met het opstellen van requirements om moet gaanen gedurende het project deze als leidraad bij alle besluiten moet gebruiken; daarnaast is het erg belangrijk om de juiste personen bij jerequirements te betrekken, zowel de stakeholders voor afstemmingvan wat ze willen, als software architecten, designers en testers voorde maakbaarheid en testbaarheid van je requirements.We hopen duidelijk te hebben gemaakt waarom het belangrijk is omdeze best practices altijd toe te passen, en we hebben hierbij een aan-tal handvatten voor het toepassen gegeven. Ben je geïnteresseerd in de achtergronden van deze best practices, ofde uitbreidingen die de auteurs hiermee op RUP hebben gedaan,neem dan contact op met een van de auteurs. •

Marion Verwey

Marion Verwey is een zeer ervarensystem analist bij Capgemini. Naasthaar werkzaamheden als systemanalist bij diverse klanten is zij ookvakgroepleider van de requirementsvakgroep binnen de sector public.Zij is bereikbaar via [email protected].

Nienke van den Brink

Nienke van den Brink een zeer erva-ren system analist bij Capgemini.Naast haar werkzaamheden als system analist bij diverse klanten iszij ook vakgroepleider van de requirements vakgroep binnen desector Financial services. Ze is be-reikbaar via [email protected].

UX TIP:Silverlight Tutorial Blogs

Er zijn een groot aantal Silverlight tutorials beschikbaar. Onderstaande lijst is van actieve blogs die regelmatig bijgehouden worden. Er zijn goede tutorials te vinden plus desource code zodat je gelijk zelf aan de slag kunt.

• Andy Beauliue: http://www.andybeaulieu.com/ Home/tabid/67/Default.aspx

• Brad Adams: http://blogs.msdn.com/brada/default.aspx • Chris Hay: http://www.screencast.com/users/chrishayuk • DotNet Curry: http://www.dotnetcurry.com/ • Jesse Liberty: http://silverlight.net/blogs/jesseliberty/ • Joe Stegman:

http://blogs.msdn.com/jstegman/default.aspx • Nikola Mihaylov:

http://blogs.msdn.com/nikola/default.aspx • Page Brooks: http://pagebrooks.com/ • Pete Brown: http://community.irritatedvowel.com/blogs/

pete_browns_blog/default.aspx • Shawn Wildermuth: http://wildermuth.com/ • Silverlight Learning Resources: http://silverlight.net/learn/ • SilverlightShow: http://www.silverlightshow.net/ • Terence Tsang: http://www.shinedraw.com/ • Tim Heuer: http://timheuer.com/blog/ • Timmy Kokke: http://geekswithblogs.net/tkokke/

Default.aspx

Page 63: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

Advertentie Sogeti

Page 64: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

.NET Laurens Ruijtenberg

Talen als Visual Basic en C# zijn voorbeelden van imperatieve talen.Binnen imperatieve talen vertel je stap-voor-stap wat de applicatiemoet doen. Dit kan bijvoorbeeld het doorlopen van een lijst zijn. In eenfunctionele taal beschrijf je wat je als eindresultaat verwacht zonderdat je exact specificeert wat er moet gebeuren om dat resultaat te be-reiken. Dat laat je over aan de compiler en een eventueel achterlig-gend framework. De toenemende populariteit vanmulticore processoren is een van de oorzaken dat soft-ware in toenemende mate complexer wordt; er zijn im-mers extra mechanismes vereist voor multithreading.In dit artikel wordt ingegaan op een aantal concepten binnen F# die helpen bij het omgaan met de eerder genoemde problemen. Dit doen we aan de hand vanfunctiecompositie, datatypes en asynchrone work-flows.

Compositie van functiesHet gebruik van functiecomposities is binnen functio-nele talen een bekende manier om complexiteit te beheersen. Metdeze samenstellingen kun je losse basisfuncties definiëren die samenherbruikbare onderdelen vormen voor nieuwe complexe functies. Ver-war dit niet met het simpelweg aanroepen van functies vanuit eenhoofdfunctie. Binnen F# is dit een rekenkundige bewerking en daar-door ook erg eenvoudig om te realiseren. Met behulp van de Com-poseLeft (<<) en ComposeRight ( >>) operators kan je eenvoudignieuwe functies samenstellen.

let SumPrices (PriceList : list<decimal>) = List.sum Price-

List

let IncludeTax OrderSum = OrderSum * 1.19M

let SumAndIncludeTax = SumPrices >> IncludeTax

let Prices : list<decimal> = [10.99M; 21.50M; 45.99M;]

let result = SumAndIncludeTax Prices

Listing 1: Een kort voorbeeld van functiecompositie

Als voorbeeld combineren we de functies SumPrices(x) en Include-Tax(x), wat resulteert in functie SumAndIncludeTax(x). In figuur 1 kunje zien dat beide functies een keten vormen. De uitvoer van SumPrices(x) is de invoer van IncludeTax(x). Met andere woorden: SumAndIncludeTax(x) is gelijk aan IncludeTax(SumPrices(x)).

Zodoende is het belangrijk dat alle datatypes in de keten met elkaarovereenkomen om type mismatches te voorkomen. De F# compilercontroleert dit door de functietypes van alle functies met elkaar te ver-gelijken. Een functietype is een korte beschrijving van de in- en uitvoertypes. Dit noteren we als ‘invoertype -> uitvoertype’. In figuur 1staat de functie IncludeTax(x) beschreven. Deze accepteert en resul-teert in een decimal, dus is het bijbehorende functietype ‘decimal ->decimal’. Het functietype van de resulterende samengestelde functiebestaat uit het parametertype van de eerste functie en het uitvoertypevan de laatste functie.

Fig. 1: Schematische weergave van een samengestelde functie

MAGAZINE64

F#: Een Functionele Oplossingbinnen een Imperatieve WereldNaast C# en Visual Basic gaat Microsoft ookF# meeleveren in Visual Studio 2010. F# is eenfunctionele taal, zoals je kon lezen in SDN Ma-gazine #99. Dit betekent dat waarden en func-ties gelijk aan elkaar zijn. Het is bijvoorbeeldmogelijk om functies als variabele mee tegeven, opnieuw te definiëren of er bewerkin-gen op uit te voeren. Daarnaast zijn variabelenen functies binnen F# standaard ‘immutable’.Zodra een waarde of functie is toegewezenmag deze niet meer veranderen, wat weervoordelen biedt bij multithreaded programme-ren. Dit heet ook wel stateless programmerenen is in puur functionele talen de manier ommet variabelen om te gaan. F# is geen puurfunctionele taal maar een multi-paradigma taal.Daardoor ondersteunt het zowel functionele alsimperatieve code.

De exacte specificatie van het eind-resultaat laat je over aan de compiler

De F# compiler vergelijkt alle functie-types van alle functies met elkaar

Page 65: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

magazine voor software development 65

DatatypesEen veelgebruikte manier om complexiteit en compositie te beheersenbinnen software zijn de concepten achter object georiënteerd soft-wareontwerp. Daarom ondersteunt F# types en classes, wat niet gebruikelijk is binnen functionele talen, maar dit biedt binnen F#enorme voordelen. Een F# class kan bijvoorbeeld eenvoudig toegevoegd worden aan een bestaande C# applicatie. Daarnaast kanF# code hierdoor ook gebruik maken van het .NET framework en kanhet door deze voordelen dienst doen als een verrijking bovenop bestaande applicaties. Door alle multithreaded code te verplaatsennaar een F# class kunnen complexe mechanismes in het C# deels worden vermeden.

Standaard types kun je vergelijken met structs in C#. Classes hetenbinnen F# concrete types. Beide specificeer je met het ‘type’-keyword.

type Person =

{

Name : string;

Age : int

Weight : int

}

Listing 2: Een F# type

Zodra je haakjes noteert achter de naam van een type, is dit een class(zie listing 3).

namespace Demo

type Person() =

[<DefaultValue>]

val mutable private _name : string

[<DefaultValue>]

val mutable private _age : int

[<DefaultValue>]

val mutable private _weight : int

member public obj.Name

with get() = obj._name

and set(value : string) = obj._name <- value

member public obj.Age

with get() = obj._age

and set(value : int) = obj._age <- value

member public obj.Weight

with get() = obj._weight

and set(value : int) = obj._weight <- value

member public obj.IsNameEqual othername =

obj._name = othername

Listing 3: Een F# ‘concrete type’ / class

In het bovenstaande voorbeeld zie je drie variabelen (_name, _age en_weight), die zichtbaar zijn binnen de klasse door het private keyword.Wat opvalt, is het gebruik van het ‘mutable’ keyword. Zoals in de inleiding is beschreven, zijn alle variabelen binnen F# standaard immutable. Met het mutable keyword kan de inhoud van een variabele aangepast worden. Dat is in het geval van classes belang-rijk, omdat deze vaak afhankelijk zijn van een variërende state. Eenproperty is daar een goed voorbeeld van omdat de achterliggendewaarde gedurende de uitvoer van het programma vaak kan verande-ren. Indien je dus de setter van een property wilt definiëren, zul je deachterliggende waarde als mutable moeten opgeven.

Fig. 2: Intellisense weergave van de Person class

Binnen een functionele taal moet elke variabele altijd direct toegewe-zen worden. Omdat dit bij properties niet altijd mogelijk is, kun je ditgedrag beïnvloeden door het DefaultValue attribuut te specificeren bijde betreffende variabele. Het gedrag van classes en properties past ei-genlijk niet binnen de denkwijze van pure functionele talen, maar F#biedt in deze gevallen het beste van beide werelden.

Als een member geen parameters bevat, dan beschouwt F# dit alseen read-only property en een member met parameters is een me-thod. Indien je binnen properties zowel get als set wilt ondersteunen,kun je de keywords ‘with’ en ‘and’ koppelen aan de bijbehorende property.

member public obj.Weight

with get() = _weight

and set(value : int) = _weight <- value

Listing 4: Een property member

Multithreading en asynchrone workflowsIn traditionele talen kan multithreaded programmeren problematischzijn, omdat je als ontwikkelaar rekening moet gaan houden met alle bijbehorende administratie op de achtergrond. Je moet een aantalmechanismes inbouwen om te voorkomen dat problemen als deadlocks en racing conditions optreden, zoals monitors, mutexes enasynchrone methoden. Als je F# applicaties stateless ontwikkelt en

gebruik maakt van immutable variabelen, zul je hier niet zo snel tegen -aan lopen. Dit dwingt je namelijk om bij elke bewerking een nieuweinstantie van de betreffende variabele aan te maken. Hierop kun je vervolgens de gewenste bewerking uitvoeren (zie figuur 3). Indien jetoch mutable variabelen gebruikt, zijn deze voordelen niet meer vantoepassing. Je kunt jezelf echter afvragen waarom die nodig zoudenzijn, gezien de voordelen die immutable variabelen binnen F# bieden.F# bevat asynchrone workflows om parallelle verwerking te onder-steunen. Daar moet je wel het één en ander voor doen. Eerst moet deparallel uit te voeren code gedefinieerd worden met behulp van hetasync type. Je mag meerdere async types definiëren die elk een

Deadlocks kunnen ontstaan als je niet stateless ontwikkelt of mutablevariabelen gebruikt

.NETC#

Variabelen zijn immutable

Page 66: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE66

andere taak op zich nemen. Je kunt het vergelijken met het makenvan een parallelle batchjob. Je hoeft jezelf niet bezig te houden met hetmaken van threads, want dat doet het F# framework allemaal voor jeop de achtergrond. Zodra alle taken gedefinieerd zijn, geef je alle asynctypes door aan Async.Parallel. Deze retourneert een collectie die uitgevoerd wordt met Async.Run. Listing 5 geeft aan hoe je asynctypes definieert en uitvoert.

let x = async { return 10 + 20 }

let y = async { return 20 + 30 }

let asyncCollection = Async.Parallel( [x; y] )

Async.Run (asyncCollection)

Listing 5: Eenvoudige parallele uitvoer

Omdat binnen functionele talen een collectie ook mag bestaan uitfuncties, kun je deze ook doorgeven aan Async.Parallel. Dit kan bij-voorbeeld een for-loop instructie zijn die asynchroon een list verwerkt.

open System

let DoSqr(x) =

async { let sqr = x * x

do Console.WriteLine(sqr.ToString()) }

let result = Async.Run (Async.Parallel

[ for i in 1 .. 100 -> DoSqr(i) ])

Listing 6: Parallele verwerking van een for-loop

Fig. 4: De output van de asynchroon uitgevoerde for-loop

In het bovenstaande voorbeeld vermenigvuldigt de func-tie DoSqr x met zichzelf en schrijft het resultaat naar deconsole. Door de functie het type async te laten retour-neren, geef je aan dat deze functionaliteit onderdeel is vande asynchronous workflow. Zodra de applicatie wordt uit-gevoerd zie je dat de volgorde van de output willekeurigis, wat aangeeft dat de code parallel is uitgevoerd.

ConclusieIn dit artikel zie je slechts een paar voorbeelden van demogelijkheden die F# biedt. Hierdoor kan de ontwikke-laar zich meer concentreren op het implementeren vanbijvoorbeeld business rules, zonder dat deze zich hoeftte bekommeren om de bijbehorende achtergrondadmini-stratie van bijvoorbeeld threads. Asynchronous workflowszijn een goed voorbeeld hiervan. Daarnaast biedt F# inte-ressante mogelijkheden op het gebied van compositie,zoals samengestelde functies, de volledige ondersteuningvan classes en de mogelijkheid om F# projecten op tenemen in bestaande C# solutions. Dit alles moet leidentot overzichtelijke, compactere en schaalbare applicaties,die gemakkelijk te implementeren zijn binnen bestaandesoftware.

Links• Microsoft F# Developer Center: http://msdn.microsoft.com/en-

us/fsharp/default.aspx• Channel 9 F# videos: http://channel9.msdn.com/tags/FSharp/• Don Syme’s weblog on the F# language and related topics:

http://blogs.msdn.com/dsyme/ •

Fig. 3: Omgang met immutable state

Laurens Ruijtenberg

Laurens Ruijtenberg is solution de-veloper bij Avanade, de wereldwijdejoint-venture tussen Microsoft en Accenture. Voor vragen of opmerkingen is hij te bereiken [email protected]

MAGAZINE66

.NETC#

19 & 20 oktober a.s.SDN Conference

35 sprekers100 sessies

Schrijf nu in!

Page 67: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

UX Fons Sonnemans

Silverlight 2.0Silverlight is een browser plugin die gebruikt kan worden door verschillende browsers op verschillende besturingssystemen. De plugin zorgt ervoor dat je eenvoudig animaties, video en audio kunt gebruiken in je browser. Silverlight bevat een subset van de functio-naliteit van Windows Presentation Foundation (WPF). Dit betekent datje kunt programmeren in je favoriete programmeertaal, in mijn gevalC#. Deze oplossing is zeer krachtig en moet dan ook gezien wordenals een alternatief voor Flash en het daarbij horende ActionScript.Silverlight applicaties draaien in een browser, dus op de client PC. Deapplicaties worden via een <object> tag opgenomen in de HTML-pa-gina. Als deze pagina opgehaald wordt start de plugin. De plugin is eensoort mini Common Language Runtime (CLR).

Fig. 1: Voorbeelden van Windows Sidebar Gadgets

De applicatie wordt vervolgens gedownload en draait daarna in deCLR. Hierdoor is de performance veel beter dan van JavaScript-ap-plicaties. Omdat een Windows Sidebar Gadget een HTML-pagina iskun je hierin ook Silverlight gebruiken. Natuurlijk moet je dan wel rekening houden met de beperkte schermgrootte.

magazine voor software development 67

Windows Sidebar Gadgets Ontwikkelen met

Silverlight 2.0Gadgets zijn mini-applicaties die draaien binnen je Live.com homepage, Windows Live Spaceof Windows Sidebar. De Windows Sidebar is een balk aan de rechterkant van je desktop waaropje gadgets kunt plaatsen waardoor je snel toegang hebt tot je favoriete applicaties en informa-tie (zie figuur 1). Deze mini-applicaties zijn eigenlijk kleine HTML-pagina’s waarin de logicameestal in JavaScript geprogrammeerd is. Deze kun je ook in Silverlight 2.0 programmeren. In dit artikel leg ik uit hoe dit moet door een eenvoudige ‘Hello World’ voorbeeld gadget te bou-wen. Om Windows Sidebar gadgets te gebruiken heb je Windows Vista of Windows 7 nodig.

Omdat een Windows Sidebar Gadgeteen HTML-pagina is, kun je hierin ookSilverlight gebruiken

Windows Sidebar GadgetEen Windows Sidebar Gadget installeer je normaal gesproken dooreen bestand met de gadget extensie te downloaden van het internet(zie figuur 2). Hiervoor heeft Microsoft de Windows Live Gallery website ontwikkeld met voornamelijk gratis te downloaden gadgets(zie link 1). Een aantal bekende zijn Buienradar.nl en Mini TV.Na installatie is de gadget zichtbaar in je Windows Sidebar.

Fig. 2: Download buienradar.gadget

Silverlight Project ontwikkelenSilverlight-applicaties ontwikkel je met behulp van Visual Studio 2008.Je moet hiervoor Service Pack 1 en de Silverlight Tools voor VisualStudio geïnstalleerd hebben (zie link 2). In Visual Studio maak je hier-voor een nieuw C# project aan van het type ‘Silverlight Application’met de naam MijnSilverlightGadget. In de daarop getoonde dialoog(zie figuur 3) geef je aan dat je aan de solution een extra project vanhet type ASP.NET Web Site wil toevoegen voor het hosten van eenHTML-pagina.

Page 68: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE68

Fig. 3: Add Silverlight Application

De user interface van een Silverlight-applicatie is beschreven in eenXAML-bestand genaamd Page.xaml (zie listing 1); de programmalo-gica is geprogrammeerd in de code-behind Page.xaml.cs (zie listing 2).In de XAML kun je eigen controls plaatsen. Voor dit voorbeeld heb ik in een MediaElement met een Border metdaarin weer een Button control toegevoegd. Het MediaElement ge-bruik ik om een video in de Background van de Border control af tespelen. Hiervoor heb ik een VideoBrush gebruikt waarvan de Sourceverwijst naar de Name van het MediaElement. Het MediaElement moetzelf niet getoond worden maar wel zichtbaar zijn; daarom heb ik dezedoorzichtig gemaakt door de Opacity op 0 te zetten. Via hetmovie_MediaEnded event wordt de video op het einde opnieuw op-gestart. Het SL.WMV videobestand heb ik aan het project toegevoegdwaarbij ik in het Properties Window de Build Action op Resource hebgezet.Als er op de knop geklikt wordt laat ik de Border ronddraaien inclusiefde video en de Button. Daarnaast verandert de tekst van de Buttongedurende de animatie in ‘Hallo wereld!’. Hiervoor heb ik een StoryBoard aan de Resources toegevoegd. In de StoryBoard is viaeen KeyFrame animatie opgegeven dat in 1,5 seconden de Angle vande Border van 0 naar 360 graden moet transformeren. Met het StoryBoard1_Completed event wordt de Angle daarna teruggezet op0. De Button1_Click event start de animatie en wijzigt de tekst van debutton in ‘Hallo Wereld!’.

<UserControl x:Class="MijnSilverlightGadget.Page"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/

presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Width="125" Height="130"

xmlns:mc="http://schemas.openxmlformats.org/

markup-compatibility/2006">

<UserControl.Resources>

<Storyboard x:Name="Storyboard1"

Completed="Storyboard1_Completed">

<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"

Storyboard.TargetName="MyRotation"

Storyboard.TargetProperty="Angle">

<SplineDoubleKeyFrame KeyTime="00:00:01.5"

Value="360" KeySpline="0.5,0,0.5,1"/>

</DoubleAnimationUsingKeyFrames>

</Storyboard>

</UserControl.Resources>

<Grid x:Name="LayoutRoot">

<MediaElement x:Name="Video1" Source="SL.wmv"

AutoPlay="True" Opacity="0.0"

MediaEnded="Video1_MediaEnded" />

<Border Margin="17" BorderBrush="#FF000000"

BorderThickness="2" RenderTransformOrigin="0.5,0.5"

CornerRadius="8">

<Border.RenderTransform>

<TransformGroup>

<RotateTransform x:Name="MyRotation"/>

</TransformGroup>

</Border.RenderTransform>

<Border.Background>

<VideoBrush SourceName="Video1" Stretch="Fill" />

</Border.Background>

<Button x:Name="Button1" Click="Button1_Click"

Content="Klik mij" HorizontalAlignment="Center"

VerticalAlignment="Center" >

</Button>

</Border>

</Grid>

</UserControl>

Listing 1: Page.xaml met extra Button control

public partial class Page : UserControl {

public Page() {

InitializeComponent();

}

void Button1_Click(object sender, RoutedEventArgs e) {

// Start animation if not already running

if (Storyboard1.GetCurrentState() != ClockState.Active){

this.Button1.Content = "Hallo wereld!";

Storyboard1.Begin();

}

}

void Video1_MediaEnded(object sender, RoutedEventArgs e){

// auto-restart

Video1.Position = TimeSpan.Zero;

Video1.Play();

}

void Storyboard1_Completed(object sender, EventArgs e){

// reset angle for the next animation

MyRotation.Angle = 0;

this.Button1.Content = "Klik mij";

}

}

Listing 2: Page.xaml.cs met de extra Button1_Click event handler

De Silverlight applicatie is voor dit voorbeeld nu klaar. Je kunt dezetesten door de applicatie op te starten met Ctrl+F5. Je project wordtdan gecompileerd waardoor je Silverlight applicatie verpakt wordt ineen .XAP-bestand (MijnSilverlightGadget.xap). Daarna wordt dezenaar de ClientBin folder van je Web Site gekopieerd. De MijnSilver-lightGadgetTestPage.aspx pagina wordt dan getoond in je browser.Deze pagina kun je overigens samen met de Default.aspx beter verwijderen uit je Web Site aangezien gadgets alleen HTML en geenASPX-pagina’s ondersteunen. Hiervoor in de plaats ga je de MijnSilverlightGadgetTestPage.html pagina gebruiken. In deze pagina staateen <object> tag waarin de ‘source’ parameter verwijst naar het MijnSilverlightGadget.xap bestand (zie listing 3). Deze pagina gebruikje om je applicatie te testen en moet je daarom als ‘Startup Page’ instellen.

UX

Page 69: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

magazine voor software development 69

<object data="data:application/x-silverlight-2,"

type="application/x-silverlight-2"

width="100%" height="100%">

<param name="source"

value="ClientBin/MijnSilverlightGadget.xap" />

<param name="onerror" value="onSilverlightError" />

<param name="background" value="white" />

<param name="minRuntimeVersion" value="2.0.31005.0" />

<param name="autoUpgrade" value="true" />

<a href="http://go.microsoft.com/fwlink/?LinkID=124807"

style="text-decoration: none;">

<img src="http://go.microsoft.com/fwlink/?LinkId=108181"

alt="Get Microsoft Silverlight"

style="border-style: none" />

</a>

</object>

Listing 3: <object> tag in MijnSilverlightGadgetTestPage.html

De gadget zou je natuurlijk ook kunnen laten communiceren met hetinternet door middel van de netwerkmogelijkheden van Silverlight(HTTP, SOAP, WCF en ADO.NET Data Services). Je kunt overigensalleen communiceren met websites die cross-domain communicatietoestaan, dit omdat je eigen computer nooit in hetzelfde domein kanzitten als de website waarmee je communiceert (zie link 4).

Gadget makenNu je de Silverlight applicatie ontwikkeld hebt, kun je hiervan een Gad-get gaan maken. Dit doe je door middel van een .gadget bestand. Ditis een ZIP-bestand waarvan de ‘zip’ extensie veranderd is in ‘gadget’.In deze zip file moeten alle bestanden opgenomen worden die samende Gadget vormen. In dit geval zijn dat:• MijnSilverlightGadget.xap met daarin de Silverlight applicatie;• Index.html met daarin het <object> tag dat verwijst naar het XAP-

bestand;• Icon.png is de afbeelding die getoond wordt in de Sidebar Gallery;• Gadget.xml manifest bestand, het XML-bestand dat de gadget de-

finieert. Het bevat een aantal parameters zoals de naam, omschrij-ving en links naar externe bestanden die toebehoren aan de gadget.

Het Index.html bestand kun je eenvoudig aanmaken door MijnSilver-lightGadgetTestPage.html bestand te kopiëren naar de ClientBin folder en daarna te hernoemen. Daarna kun je diverse “overbodige”onderdelen uit deze HTML verwijderen, bijvoorbeeld de twee <script>tags, de errorLocation <div> en de <iframe>. De width en de heightvan de body pas je via de inline CSS aan naar 130 bij 130 pixels.

Tot slot moet je nog drie belangrijke aanpassing aanbrengen in de<object> tag:1. De width en height op 125 bij 130 pixels zetten. Deze width is 5

pixels minder dan de width van de body. Dit is nodig omdat andersde gadget niet gesloten kan worden. In diverse bronnen op het in-ternet wordt een andere oplossing voor dit probleem beschreven.Hierbij wordt een extra Windowless parameter met de value ‘true’toegevoegd. Deze oplossing veroorzaakt helaas een probleem metde MouseEvents events; het klikken op onze button werkt dan nietmeer.

2. De value van de ‘source’ parameter moet gewijzigd worden van‘ClientBin/MijnSilverlightGadget.xap’ naar ‘x-gadget:///MijnSilver-lightGadget.xap’.

3. De ‘onerror’ parameter moet verwijderd worden aangezien er in ditgeval geen foutafhandeling nodig is.

Dit resulteert uiteindelijk in een Index.html zoals weergegeven in listing 4.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>MijnSilverlightGadget</title>

<style type="text/css">

body {

padding: 0px;

margin: 0px;

width: 130px;

height: 130px;

}

</style>

</head>

<body>

<div id="silverlightControlHost">

<object data="data:application/x-silverlight-2,"

type="application/x-silverlight-2" width="125"

height="130">

<param name="source"

value="x-gadget:///MijnSilverlightGadget.xap" />

<param name="background" value="white" />

<param name="minRuntimeVersion" value="2.0.31005.0" />

<param name="autoUpgrade" value="true" />

<a href="http://go.microsoft.com/fwlink/?LinkID=124807"

style="text-decoration: none;">

<img src="http://go.microsoft.com/fwlink/?LinkId=108181"

alt="Get Microsoft Silverlight"

style="border-style: none" />

</a>

</object>

</div>

</body>

</html>

Listing 4: Index.html

In het voorbeeld is daarna het Silverlight-logo in een 64 bij 64 pixelPNG-afbeelding geplaatst en opgeslagen als ‘Logo.png’ in de ‘Client-Bin’ folder.Tot slot moet je een XML-bestand met de naam ‘Gadget.xml’ toe-voegen aan de ‘ClientBin’ folder. Dit XML-bestand heeft een voorge-schreven structuur die beschreven staat op MSDN (zie link 7). Voor dit voorbeeld heb ik o.a. de name op ‘Mijn Silverlight Gadget’gezet, mijzelf als author opgenomen, een verwijzing gemaakt naar hetIcon.png bestand en de Index.html: zie listing 5.

<?xml version="1.0" encoding="utf-8" ?><gadget>

<name>Mijn Silverlight Gadget</name><namespace>ReflectionIT.MijnSilverlightGadget</namespace><version>1.0.0.0</version><author name="Fons Sonnemans"><info url="www.reflectionit.nl" />

</author><description>Hallo Wereld voorbeeld gadget</description><icons>

<icon height="64" width="64" src="Icon.png" /></icons><hosts>

<host name="sidebar"><base type="HTML" apiVersion="1.0.0" src="Index.html" /><permissions>Full</permissions><platform minPlatformVersion="1.0" /><defaultImage src="Icon.png" />

</host></hosts>

</gadget>

Listing 5: Gadget.xml manifest bestand

UX

Page 70: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

MAGAZINE70

UX

Gadget installeren Je bent nu klaar met het ontwikkelen van de gadget. De Solution Explorer in Visual Studio is weergegegeven in figuur 4. De gadget moetgeïnstalleerd worden. Dit doe je door de 4 bestanden van de Client-Bin folder in een ZIP-bestand te plaatsen. Dit ZIP-bestand hernoem jenaar ‘MijnSilverlightGadget.gadget’. Door dit bestand daarna te ope-nen wordt de gadget geïnstalleerd en daarmee zichtbaar in de Wind-ows Sidebar (zie figuur 5). Bovenaan in de Sidebar bevindt zich een +icoon. Door hierop te klikken kun je extra gadgets aan je Sidebar toe-voegen via de Gadget Gallery. De ‘Mijn Silverlight Gadget’ is nu na-tuurlijk ook in deze Gallery opgenomen (zie figuur 6). De Manifestgegevens worden bij de details weergegeven. Vanuit de Gallery kun jeook extra gadgets online downloaden.

Gadget verzenden naar Microsoft live.comNu je klaar bent zou je natuurlijk deze gadget ook kunnen toevoegenaan de Gadget Gallery van Microsoft live.com zodat iedereen dezegadget kan downloaden. Dit kan door de gadget te verzenden naarMicrosoft. Microsoft behoudt zich het recht voor om inzendingen tebeoordelen en af te wijzen. Wil je de gadget veiliger maken, dan dienje deze te controleren op schadelijke code. Vergeet ook niet je gadgette ondertekenen met een certificaat, zodat gebruikers weten wie hetgadget heeft gemaakt.

Silverlight Gadgets in Windows Vista 64 bits Indien je een 64bits versie van Windows Vista gebruikt, werken degadgets die gebruik maken van Silverlight helaas niet. Dit komt omdatSilverlight alleen een 32 bits-applicatie is. Dit probleem kun je oplos-sen door je Windows Sidebar af te sluiten en daarna de 32bits-versievan de Windows Sidebar op te starten (C:\Program Files (x86)\Wind-ows Sidebar\sidebar.exe). Helaas heeft Microsoft nu nog geen moge-lijkheid om dit binnen de 64bits operating systemen te gebruiken.

Project TemplateOp de blog van Ioan Lazarciuc (zie link 10) staat een Visual Studio Pro-ject Template voor het ontwikkelen van Silverlight Sidebar Gadgets.Deze Template ondersteunt een aantal extra mogelijkheden zoals Set-tings en Flyout. Helaas maakt dit template gebruik van de Windowlessparameter. Toch raad ik aan om de oplossing te bestuderen aangeziener diverse nuttige helper functies gebruikt worden.

ConclusieHet bouwen van Windows Sidebar gadgets met behulp van Silverlightis niet echt complex. Er is wel een aantal zaken waar je rekening meemoet houden. Natuurlijk moet je goed bedenken wat je in de beperkte

ruimte van een gadget gaat presenteren. De voorbeeldapplicatiemaakt slechts zeer beperkt gebruik van de mogelijkheden van Silver-light 2.0. Juist door die te benutten kun je de mooiste mini-applicatiesbouwen. De toekomst zal uitwijzen of Silverlight ook hiervoor veel ge-bruikt gaat worden. Ik ben zeer hoopvol gestemd.

Links1. Windows Live Gallery: http://gallery.live.com2. Silverlight ontwikkelen: http://silverlight.net/GetStarted/3. HTTP Communication and Security with Silverlight:

http://msdn.microsoft.com/en-us/library/cc838250(VS.95).aspx4. Windows Live Gallery voor ontwikkelaar

http://gallery.live.com/devcenter.aspx5. Sidebar Gadget Forum: http://go.microsoft.com/fwlink/?Lin-

kID=1425876. Gadget verzenden naar Windows Live Gallery:

http://gallery.live.com/submit.aspx7. Gadgets for Windows Sidebar Manifest:

http://msdn.microsoft.com/en-us/library/bb508509(VS.85).aspx8. Silverlight Sidebar Gadgets on Windows Vista 64-bit edition:

http://adamkinney.com/blog/323/default.aspx9. Updated Silverlight Color Picker Gadget: http://www.design-

erwpf.com/2008/12/03/updated-silverlight-color-picker-gadget/10. Creating a Vista Sidebar Gadget Using Microsoft Silverlight:

http://www.lazarciuc.ro/ioan/2008/08/02/creating-a-vista-side-bar-gadget-using-microsoft-silverlight/ •

Fig. 6: Gadget Gallery

Fig. 4: Solution Explorer Fig. 5: Windows Sidebar

Fons Sonnemans

Fons Sonnemans is een zelfstan-dige trainer en software-ontwikke-laar. Hij heeft zich gespecialiseerd inC#, ASP.NET, Object Oriëntatie,SQL Server en Silverlight. Hij volgtde nieuwste ontwikkelingen op devoet en verwerkt deze direct in zijninhouse maatwerk traingen. Fons iste bereiken via fons.sonnemans@

reflectionit.nl of www.reflectionit.nl

Page 71: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

Advertentie Avanade

Page 72: Papendal, Arnhem SCHRIJF NU IN! · Adverteerders Macaw 2 VNU 20 Barnsten/Embarcadero 27 Bergler 28 Microsoft 36-37 Alladdin 41 Sybase iAnywhere 45 ... voor het draaien van applicaties

Advertentie Bridge Incubation Group BV