SDN Magazine 116Nummer 116 maart 2013 SDN Magazine verschijnt elk kwartaal en is een uitgave van...

36
Nummer 116 maart 2013 SDN Magazine verschijnt elk kwartaal en is een uitgave van Software Development Network www.sdn.nl IN DIT NUMMER O.A.: HTML5 Builder DataSnap Clients < Two Approaches to Sub-classing Components Compared < Mono en Android, een prima koppel < Continuous Delivery / Deployment met TFS Azure < Windows Azure Websites < SOFTWARE DEVELOPMENT NETWORK MAGAZINE 116 ISSN: 2211-6486

Transcript of SDN Magazine 116Nummer 116 maart 2013 SDN Magazine verschijnt elk kwartaal en is een uitgave van...

Nummer 116 maart 2013 SDN Magazine verschijnt elk kwartaal en is een uitgave van Software Development Network

www.sdn.nl

IN DIT NUMMER O.A.:

HTML5 Builder DataSnap Clients <

Two Approaches to Sub-classing Components Compared <

Mono en Android, een prima koppel <

Continuous Delivery / Deployment met TFS Azure <

Windows Azure Websites <

SOFTWARE DEVELOPMENT NETWORK

MAGAZINE

116

ISSN: 2211-6486

magazine voor software development 3

ColofonUitgave:

Software Development Network

Eenentwintigste jaargang

No. 116 • maart 2013

Bestuur van SDN:

Remi Caron, voorzitter

Rob Suurland, penningmeester

Marcel Meijer, secretaris

Redactie:

Marcel Meijer

([email protected])

Aan dit magazine

werd meegewerkt door:

Roel Hans Bethlehem, Bob Swart, Maarten

van Stam, Alexander Meijers, Remi Caron,

Marcel Meijer en natuurlijk alle auteurs!

Listings:

Zie de website www.sdn.nl voor eventuele

source files uit deze uitgave.

Contact:

Software Development Network

Postbus 506, 7100 AM Winterswijk

Tel. (085) 21 01 310

Fax (085) 21 01 311

E-mail: [email protected]

Vormgeving en opmaak:

Reclamebureau Bij Dageraad, Winterswijk

www.bijdageraad.nl

©2013 Alle rechten voorbehouden. Niets uit

deze uitgave mag worden overgenomen op

welke wijze dan ook zonder voorafgaande

schriftelijke toestemming van SDN. Tenzij

anders vermeld zijn artikelen op persoonlijke

titel geschreven en verwoorden zij dus niet

noodzakelijkerwijs de mening van het be-

stuur en/of de redactie. Alle in dit magazine

genoemde handelsmerken zijn het eigen-

dom van hun respectievelijke eigenaren.

AdverteerdersPGGM 2

Achmea 7

CSC 16

Barnsten Embarcadero 23

Microsoft 24

Delta-N 35

Macaw 36

Adverteren?

Informatie over adverteren en de adverten-

tietarieven kunt u vinden op www.sdn.nl

onder de rubriek Magazine.

voorwoordBeste SDN magazine lezer,

Het is weer gelukt om een magazine te maken met mooie artikelen. Zoals je gemerkt

hebt, wordt het wel steeds lastiger om de geplande publicatie datum te halen. Onze

excuses daarvoor, maar we proberen goede en interessante artikelen te brengen en

dat neem tijd in beslag. Mocht je nog plannen hebben voor een artikel, dan kun je

contact met mij opnemen. Op de SDN website als je op het magazine menu klikt de

kopij aanlever data. Voor het volgende magazine 117 is dat 1 april en dat is geen

geintje.

Het jaar begon koud met sneeuw, vleugjes van Elfstedentocht dromen en bijbe ho-

rende overlast. Het begint nu toch weer gauw lente te worden en dan komen er weer

mooie dingen aan. Hebben jullie je Windows Phone 7.5 al geüpdate naar 7.8?

Hoeveel van jullie hebben al een Surface RT gekocht, nu hij in Nederland verkrijgbaar

is? Of zitten we nu met zijn allen te wachten op een Surface Pro ;-) In dit magazine

staat een klein stukje over de Surface Pro. Ik gebruik nu al dagelijks een dergelijk

apparaat en mijn eerste ervaringen ga ik met jullie delen.

Dat is natuurlijk niet het enige artikel. De onderwerpen lopen uiteen van continues

deployment vanuit TFS naar Domain Specific Languages. Maar ook Windows Azure

Mobile Services en Windows Azure Websites komen aan bod. Ben je meer van

Mobile development, dan ook deze keer een mooi artikel over Android development

voor de .NET developer. Bob en Cary Jensen maken het af voor de Delphi sectie.

Kortom voldoende om je kennis weer op te halen.

Rest mij jullie veel leesplezier te wensen en vooral uit te nodigen om ook eens te

schrijven voor ons SDN magazine. Korte artikelen of ervaringen komen altijd van pas

en ik beloof je dat je artikel ook altijd geplaatst zal worden.

Met vriendelijke leesgroet,

Marcel

Inhoud

03 VoorwoordMarcel Meijer

04 Inhoudsopgave

04 Agenda

05 HTML5 Builder DataSnap ClientsBob Swart

09 Azure mobile services: Een ‘one stop’ backend voor jouw App

Didier Caron

12 Two Approaches to Sub-classing Components Compared

Cary Jensen

17 Back to BasicMichiel van Otegem

18 Mono en Android, een prima koppel

Willem Meints

22 Windows Azure Websites Marcel Meijer

25 Modeling your domain driven design in UML

Sander Hoogendoorn

28 Unit Testen kan veel makkelijkerWouter de Kort

30 Continuous Delivery /Deployment met TFS Azure 2012 Release

Hassan Fadili

30 Using the ObjectManagerRobert Jan Boeije

• Microsoft TechDays Nederland

7/8 maart 2013

Den Haag

• SDE 1

18 maart 2013

• Global Windows Azure Bootcamp

27 april 2013

• SDE 2

7 juni 2013

• TechEd Europe

25-28 juni 2013

Madrid

• SDE 3

20 september 2013

• PDC of toch weer een //Build?

oktober 2013

• SDC

25/26 november 2013

Agenda 2013

DELPHI Bob Swart

HTML5 Builder DataSnap ClientsEmbarcadero RAD Studio ontwikkelaars hebben sinds versie XE3 de beschikking over HTML5Builder - een nieuwe versie van de tool die vroeger ook als RadPHP of zelfs Delphi for PHP bekend stond. Met HTML5 Builder kunnen we Client (alleen JavaScript) en Server (JavaScripten PHP) toepassingen maken voor zowel Web als Mobile. Dat is op zich leuk, maar voor Del-phi ontwikkelaars is het leukste feit dat we HTML5 Builder ook kunnen gebruiken om er DataSnap clients mee te maken voor Delphi DataSnap REST Servers. In dit artikel laat ik zienhoe dat in zijn werk gaat.

DataSnap XE3 REST ServerOm een DataSnap REST Server te maken heb je de Enterprise editievan Delphi XE3 (of C++Builder) nodig.. Die zitten allebei net als HTML5Builder in RAD Studio XE3 Enterprise. Vanuit Delphi Enterprise kun jevia File | New - Other in de DataSnap Server categorie kiezen vooreen DataSnap REST Application of een DataSnap WebBroker Appli-cation. In beide gevallen kies ik voor een ISAPI DLL om de DataSnapServer te deployen en in de tweede pagina van de DataSnap Wizardkunnen we dan specifieke features selecteren:

Ik wil graag authenticatie (wie ben je) en authorisatie (wat mag je doen),dus deze twee features zet ik aan. Daarnaast is een server methodclass noodzakelijk en het is fijn als er al vast wat voorbeeld methodesin zitten (EchoString en ReverseString). Tot slot is er een optie voorMobile Connectors waar we even naar kunnen kijken: deze kan ge-bruikt worden om proxies te laten generen voor mobile clients (in Javavoor Android of Blackberry, in C# voor Silverlight, Objective-C voor

iOS, of Free Pascal voor iOS). Deze gaan we deze keer niet gebruiken:HTML5 Builder heeft zijn eigen manieren om een DataSnap REST Server te importeren en gebruiken.De laatste pagina van de wizard laat ons een base class kiezen voorde server method class. In het geval van REST is een TComponent ofTDataModule voldoende en biedt de laatste de mogelijkheid om alscontainer voor non-visuele componenten te dienen. Een TDSServer-Module is met name bruikbaar voor DBX connecties en voegt vooreen REST server weinig extra's toe vergeleken met een TDataModule.

Het gegenereerde project (dat ik opgeslagen heb als DataSnapREST.dproj) heeft een WebModuleUnit en een ServerMethod-sUnit. In de Server Methods unit staat de definitie van onze server method. Deze bevat standaard al een tweetal voorbeeld server methods: EchoString en ReverseString. Hier kunnen we bijvoorbeeldeen derde functie aan toevoegen, GetServerTime die de tijd van deweb server teruggeeft:

magazine voor software development 5

DELPHI

type

{$METHODINFO ON}

TServerMethods1 = class(TDataModule)

private

{ Private declarations }

public

{ Public declarations }

function EchoString(Value: string): string;

[TRoleAuth('guest','admin')]

function ReverseString(Value: string): string;

[TRoleAuth('admin')]

function ServerTime: TDateTime;

end;

{$METHODINFO OFF}

De implementatie hiervan laat ik aan de fantasie van de lezer over. Letop dat de EchoString geen rol vereist, maar de ReverseString de rol"guest" nodig heeft, en de ServerTime functie zelfs de rol "admin".Voor het uitdelen van de rollen moeten we naar de Web Module unitkijken en daar de OnAuthenticate event handler invullen (om na hetinloggen de rollen "guest" of "admin" uit te delen) net als de OnAut-horize (om voor het uitvoeren van een server method te checken of degebruiker de juiste rol wel heeft). Dat gaat als volgt:

procedure TWebModule1.DSAuthenticationManager1UserAuthenti-

cate(

Sender: TObject; const Protocol, Context, User, Password:

string;

var valid: Boolean; UserRoles: TStrings);

begin

valid := (User = Password); // very secure!! (NOT)

if LowerCase('user') = 'bob' then

UserRoles.Add('admin')

else

UserRoles.Add('guest');

end;

procedure TWebModule1.DSAuthenticationManager1UserAuthorize(

Sender: TObject; EventObject: TDSAuthorizeEventObject;

var valid: Boolean);

var

UserRole: String;

begin

if Assigned(EventObject.AuthorizedRoles) then

begin

valid := False; // pessimistic authorization

for UserRole in EventObject.UserRoles do

valid := valid or (EventObject.AuthorizedRoles.

IndexOf(UserRole) >= 0);

end

else

valid := True

end;

Een DataSnap REST Server kan uitsluitend via http of https commu-niceren (en dus niet over TCP/IP - het protocol dat meer geschikt isvoor DBX connecties). Ook kunnen we geen DataSnap(encryptie/compressie) filters toepassen op REST connecties, dusraad ik iedereen altijd aan om https:// te gebruiken om in ieder gevalhet data verkeer te beveiligen.Bovenstaande voorbeeld DataSnap REST Server is via https te benaderen op het internet (voor wie met HTML5 Builder wil spelen) als https://www.bobswart.nl/cgi-bin/DataSnapREST.dll

HTML5 Builder ClientHTML5 Builder is een tool van Embarcadero - ooit begonnen onder denaam Delphi for PHP, en later RadPHP - die gebruik maakt van zowelPHP als JavaScript. De PHP code wordt vooral aan de server kantuitgevoerd, de JavaScript aan de client kant in de browser.We kunnen met HTML5 Builder zowel server als client toepassingenmaken en zowel web als mobile toepassingen. De eenvoudigste demois een Server Web toepassing, die we kunnen starten met Home | New | HTML5 Builder Projects - Server Web Application.In de PHP form je we dan krijgen kunnen we verschillende compo-nenten plaatsen vanuit het Tool Palette. Ook al is de taal hier PHP enJavaScript, de manier van werken doet toch erg aan Delphi denken inderdaad.

Om een verbinding te maken met de DataSnap REST server, moetenwe een DataSnap REST client module toevoegen aan het Server Webproject. Dat kan via Home | New | Other Files - DataSnap REST ClientModule.Er volgt nu een dialoog waarin we de gegevens kunnen invullen ommet de DataSnap REST server te kunnen communiceren:

Voor het protocol kunnen we kiezen uit http of https (https raad ik aan).Als language kunnen we PHP of JavaScript laten genereren. Daarnamoeten we de Host invullen (www.bobswart.nl) de Port (443 voorhttps), het URL path (dat is /cgi-bin/DataSnapREST.dll) en tot slot deUser name en Password. Om toegang te krijgen moeten die gelijk zijn,en als de User name "Bob" is, dan krijgen we ook de rol "admin" zoalswe eerder in de DataSnap server zelf hebben aangegeven.

Het resultaat is twee nieuwe units die worden toegevoegd aan hetHTML5 Builder project: een ClientClassesUnit1.php en een ClientModuleUnit1.php.

Op de ClientModuleUnit1.php staat een DSRestConnection compo-nent dat verantwoordelijk is voor de verbinding naar de DataSnapREST server. De properties Protocol, Host, Port, URLPath, UserNameen Password kunnen we hier nog bijstellen indien nodig. Er is ook eenfunction readServerMethods1Client die een instantie teruggeeft van

MAGAZINE

6

DELPHI

de TServerMethods1 (een proxy naar de TServerMethods1 class vande DataSnap server).De TServermethods1Client class zelf kunnen we terugvinden in deClientClassesUnit1.php unit. Hier kunnen we ook de definities zien vande proxy functions EchoString, ReverseString en ServerTime.

Om een instantie van de TServerMethods1Client class te maken moeten we even terug naar het main form en daar bovenaan het volgende toevoegen:

require_once("ClientModuleUnit1.php");

Dat is te vergelijken met het toevoegen van de ClientModuleUnit1 aande uses clause. Hierna kunnen we van de ClientModuleDataModule1de ServerMethods1Client gebruiken om de ReverseString, EchoStringof ServerTime aan te roepen, bijvoorbeeld als volgt:

class Page1 extends Page

{

public $Button1 = null;

public $Label1 = null;

function Button1Click($sender, $params)

{

global $ClientModuleDataModule1;

$this->$Label1->Caption =

$ClientModuleDataModule1->ServerMethods1Client->Rever-

seString("test")->result;

}

}

Het resultaat wordt zichtbaar in de caption van het label. Niet echt wereldschokkend, maar het "bewijst" dat we vanuit HTML5 Buildereen verbinding kunnen maken en kunnen communiceren met een Delphi XE3 DataSnap REST server. De rest is een kwestie van behoefte en inspiratie om hier iets moois van te maken...•

Bob Swart

Bob Swart is werkzaam in de IT

sinds 1983 en heeft daarbij een

voorliefde voor (Turbo) Pascal en

Delphi. Bob spreekt regelmatig op

(internationale) conferenties over

Delphi en heeft honderden artikelen

geschreven, alsmede zijn eigen

Delphi cursusmateriaal voor Delphi

trainingen en workshops. Behalve

voor het geven van trainingen, is Bob ook beschikbaar voor

consultancy, coaching, ontwerp- en bouwwerkzaamheden, of

andere ondersteuning op het gebied van software ontwikkeling

met Delphi – voor zowel Win32 als .NET. Sinds de zomer van

2007 is Bob ook reseller van CodeGear producten zoals Delphi

en RAD Studio. Bob Swart Training & Consultancy is gevestigd in

Helmond Brandevoort, en beschikt over een eigen trainingsruimte

van ruim 42 vierkante meter, inclusief een testlab voor alle

mogelijke toepassingen. De voorliefde van Bob voor Pascal en

Delphi heeft hij ook tot uiting laten komen in de namen van zijn

kinderen Erik Mark Pascal en Natasha Louise Delphine.

SDN EVENT& ALV 18 MAART A.S.

ACHMEA EUREKO CONFERENCE CENTER-ZEISTALV 09:00 - 09:45 UUREVENT 10:00 - 16:30 UURHandelsweg 2, 3707 NH Zeist

Onderwerpen o.a.:

• nServiceBus

• Windows Azure

• OAuth

• Delphi

• Solid

Een evenement met diverse

topsprekers, waaronder

Sander Hoogendoorn, Dennis

van der Stelt en Bob Swart.

CLOUD Didier Caron

Getting StartedVoordat je instanties kunt aanmaken in de Azure portal moet je jouwaccount aanmelden voor de preview. Dit kun je eenvoudig en koste-loos doen via http://www.windowsazure.com/nl-nl/home/features/preview/ en is binnen een paar minuten geregeld. De service bundelteen aantal Cloud diensten en zorgt voor een eenvoudige manier omdeze diensten te benaderen. Op het moment van schrijven bevat deservice de volgende diensten / mogelijkheden:

• Authenticatie op basis van OAuth• Autorisatie met behulp van scripting• Data, vergelijkbaar met Azure Table Storage• Push Notifications• Scheduled Jobs

Microsoft heeft nog niet duidelijk gemaakt welke diensten en featureser bij komen maar doordat de service in Azure gehost wordt zijn demogelijkheden nagenoeg eindeloos. We zullen in dit artikel laten zienhoe je onderdelen van de dienst aan de Azure ServiceBus koppelt omde App te koppelen aan jouw Cloud of hybride landschap.

‘Bring your own device’Het moet Microsoft opgevallen zijn dat de ‘bring your own device’ gedachte steeds meer geadopteerd wordt in de zakelijke markt. Daarnaast is het marktaandeel van de Microsoft platformen op dit moment nog niet erg groot. Er wordt gewerkt aan SDK’s voor de verschillende smartphones en tablet operating systemen waarvan eral een aantal beschikbaar zijn. Uiteraard voor de Microsoft platformenmaar ook voor de platformen van de concurrenten. Op dit momentzijn er SDK’s voor• Windows Phone 8 Apps• Windows Store Apps• IOS

Een Android SDK is onderweg waardoor je alle grote platformen kuntbedienen met dezelfde backend. Het minimaliseert de benodigde ef-fort om je app te verspreiden voor de verschillende platformen en helptjou om een consistente belevenis te bezorgen bij jouw gebruikers.

Mocht jouw app een succes zijn dan kun je de service eenvoudig opschalen door over te stappen van de gratis instance naar een reserved instance. Hierdoor kun je meer rekenkracht, grotere databa-ses en meer scheduled jobs laten draaien om jouw grote user basevan dienst te kunnen zijn.

Het ScenarioIn dit artikel gaan we kijken naar scripts vanuit de data sectie en hoewe vanuit deze scripts andere systemen kunnen voorzien van data diewe verzamelen in een App. Deze scripts, die je ook kunt draaien vanuit Scheduled Jobs, zijn op dit moment de meest voor de handliggende plek om aan andere systemen te koppelen. Scheduled Jobszijn scripts die periodiek worden gestart. In de gratis versie kun je maximaal 1 scheduled job per instantie maken, zodra je opschaalt kunje meer jobs laten draaien.

We gaan voor de code voorbeelden uit van het volgende scenario:We hebben een App voor een webwinkel waarbij gebruikers een wish-list kunnen samenstellen van producten. De producten en de wensenvan gebruikers worden opgeslagen in twee tabellen die gebruik makenvan de Data Services van de dienst. De App stuurt notificaties naar degebruiker als producten op de wish-list in prijs dalen en gebruikerskunnen vanuit de app de producten kopen. Op het moment dat eengebruiker besluit een product aan te schaffen wordt dit doorgestuurdnaar het order verwerkingssysteem. Een vereenvoudigde representa-tie van de architectuur vind je in figuur 1.

Fig. 1: Fictieve architectuur van een App

Azure mobile services is een nieuwe Microsoft Azure dienst die je de basis voor een backendvan een app levert. De service is momenteel een preview en je kunt 10 gratis instanties aanmaken op 1 Azure account.

Azure mobile services: Een ‘one stop’ backend voor jouw App

Koppel de App aan jouw Cloud of hybride landschap met de Azure ServiceBus

magazine voor software development 9

CLOUD

Let op, de code in dit artikel is vooral om aan te geven wat de moge-lijkheden zijn. Ik raad niet aan om deze code 1 op 1 te gebruiken in eenproductie scenario.

DataWe gebruiken de dataservice voor het ophalen van de producten enhet opslaan van de wensen. De dataservice lijkt sterk op de AzureTable Storage dienst met flexibele kolommen en meerdere indexenper tabel. We maken twee tabellen aan via de management portal. Ikzal niet ingaan op het aanmaken van de tabellen want je wordt stapvoor stap door het proces geleid door de management portal. Nadatde tabellen zijn aangemaakt, zal je zien dat de tabellen nog geen kolommen bevatten. De kolommen worden aangemaakt zodra er 1 record wordt opgeslagen in een tabel. De kolommen komen danovereen met de attributen van het object dat je hebt opgeslagen in detabel. Zodra je een attribuut toevoegt aan het model en een rij aanmaakt voegt de dienst een kolom automatisch toe aan de tabel.In Listing 1 zie je een voorbeeld van een model dat gebruikt kan worden voor het opslaan in een tabel met de naam ‘Wish’. Daarnaastzie je een manier om rijen toe te voegen aan de tabel.

Fig. 2: Rechten van de tabel in de Azure portaal

[DataContract]

public class Wish

{

[DataMember]

public long Id { get; set; }

[DataMember]

public long ProductId { get; set; }

[DataMember]

public bool IsOrdered { get; set; }

}

public class WishService : IWishService

{

private readonly IMobileServiceTable<Wish> _table;

public WishService(MobileServiceClient client)

{

_table = client.GetTable<Wish>();

}

public async Task Add(Wish wish)

{

try

{

await _table.InsertAsync(wish);

}

catch (Exception e)

{

Tracer.Critical("Could not save wish");

}

}

}

Listing 1: Code voor het toevoegen van een wens

AutorisatiesZodra je in de Azure Management Portal een tabel opent zie je eenmenu met 4 opties:- BROWSE, bekijk de rijen die opgeslagen zijn in de tabel.- SCRIPT, schrijf scripts voor de verschillende acties op de tabel.- COLUMNS, bekijk en wijzig de indexen op de verschillende kolommen die zijn aangemaakt.

- PERMISSIONS, bekijk en wijzig de autorisaties op de tabel voor deverschillende acties op de tabel.

We passen de rechten aan voor de Wish tabellen zodat alleen geauthenticeerde gebruikers kunnen schrijven naar de tabel. We hebben de volgende keuzes:

- Everyone, iedereen mag schrijven naar de tabel.- Anybody with the application key, iedereen die de applicatie sleutelheeft mag schrijven naar de tabel.

- Only Authenticated Users, alleen geauthenticeerde gebruikersmogen schrijven naar de tabel.

- Only Scripts and Admins, alleen scripts en admins mogen schrij-ven naar de tabel.

In dit geval kiezen we voor alle acties op de tabel voor Only Authenti-cated Users omdat we de gebruikers moeten identificeren bij het wegschrijven van hun wensen. De functie die is gedefinieerd op deverschillende acties bevat standaard een user parameter die we kunnen gebruiken om de aanvrager te identificeren.

ScriptsNu de authenticatie is geconfigureerd kunnen we op verschillendeplekken scripts aanpassen om gebruikersinformatie op te slaan bij derecords. We klikken in hetzelfde scherm op de button SCRIPT waar-

MAGAZINE

10

CLOUD

mee we een javascript (nodejs) editor openen. Nodejs is een javascriptbibliotheek dat je in staat stelt om server-side of netwerk gerelateerdejavascript te schrijven. Het wordt veelal gebruikt om applicaties te bouwen die intensief gebruik maken van real-time data. Microsoft heeftvoor veel Azure componenten kant-en-klare modules waardoor hetschrijven van scripts relatief eenvoudig is. Aan de andere kant laat demicrosoft documentatie van de nodejs componenten nog wat te wensen over waardoor het in het begin lastig kan zijn. In de editor kunnen we kiezen voor welke actie we het script willen aanpassen. Je kunt kiezen uit de volgende acties:

- INSERT, voor het wegschrijven van de rij.- READ, voor uitvoeren van de query.- UPDATE, voor het uitvoeren van de update.- DELETE, voor het verwijderen van de rij.

We voegen 1 regel code toe aan de INSERT actie om de unieke sleutel van de gebruiker op te slaan in de rij in de tabel. Doordat hetschema van de tabel dynamisch is, wordt er automatisch een kolomopgenomen met de naam UserId.

function insert(item, user, request) {

// voeg de gebuiker toe om er zeker van te zijn

// dat we de wensen van de gebruiker kunnen vinden

item.UserId = user.userId;

// voer de uitvraag uit

request.execute();

}

Listing 2: Script dat de gebruiker toevoegt aan een rij

Om er zeker van te zijn dat gebruikers alleen hun eigen wensen kun-nen ophalen voegen we ook aan de READ actie een aantal regels toe.

function read(query, user, request) {

// voeg de gebuiker toe om

// de wensen te filteren

query.where({ UserId: user.userId });

// voer de uitvraag uit

request.execute();

}

Listing 3: Script dat wordt gebruikt bij alle lees opdrachten op detabel

Bij elke lees en schrijf actie worden nu onze scripts gedraaid en kunnen gebruikers alleen nog hun eigen records opvragen.

Zodra een gebruiker een gewenst artikel wilt kopen, wordt de aan-koop naar het verwerkingssysteem gestuurd. We passen het UPDATEscript aan zodat de order via de Azure ServiceBus wordt aangeleverdaan het verwerkingssysteem.

function update(item, user, request) {

// update de rij

request.execute();

// als het product is bestelt, stuur het door

// voor verdere afhandeling

if(item.IsOrdered) {

// zet het product op een queue in de

//ServiceBus voor verdere verwerking

processOrder(item,user);

}

}

function processOrder(item,user) {

// laad de node.js azure componenten

var azure = require("azure");

// stel de servicebus namespace and sleutel in

var namespaceName = '<servicebusname>';

var namespaceKey = '<servicebuskey>';

// Maak de connectie naar de servicebus

var serviceBusService = azure.createServiceBusService(

namespaceName, namespaceKey);

// stringify het product, zodat we hem later

// als JSON ontvangen

serviceBusService.sendQueueMessage('orders',

JSON.stringify(item),

function(error) {

if (!error) {

console.log('sent message');

}

else {

console.log('did not send message');

}

});

}

Listing 4: Het UPDATE script van waaruit wordt gekoppeld met deAzure ServiceBus

ConclusieWe hebben in dit artikel een overzicht proberen te schetsen van demogelijkheden van Azure Mobile Services en hoe je jouw App kuntaansluiten op een nieuwe of bestaande Service Bus. In mijn optiek isde service een geweldige tool om snel de basis voor een fantastischeApp te leggen. Het biedt veel mogelijkheden en je bent vrij in welke on-derdelen je wilt gebruiken. Het zal ervoor zorgen dat jouw backendschaalbaar en toekomst vast is. Het is nu tijd om zelf de service teontdekken en te kijken wat het voor jou kan betekenen! •

Didier Caron

Didier is een consultant met een

grote interesse voor cloud techno-

logie. Hij heeft ervaring met een

gedeelte van Microsoft stack (Azure,

Dynamics CRM, SharePoint, MVC,

WPF en WP7). Hij verdiept zich op

dit moment in WinRT en WP8 en

werkt op dit moment als contractor voor de CRM service lijn van

Avanade.

magazine voor software development 11

De service is een geweldige tool omsnel de basis voor een fantastischeApp te leggen

DELPHI Cary Jensen

Delphi is an object oriented programming language. Unless you write nothing but console applications, this fact is obvious. For example, when your application includes either a form ora data module, the class that defines the form or data module is a descendent of an existingclass. In the case of a form, it is a TForm descendant, and in the case of a data module it is aTDataModule descendant.

Two Approaches to Sub-classingComponents Compared

type

TEasyReaderDBGrid = class(Vcl.DBGrids.TDBGrid)

private

{ Private declarations }

FDict: TDictionary<string, TField>;

public

{ Public declarations }

constructor Create(AOwner: TComponent); override;

destructor Destroy; override;

procedure InitializeDictionary(DataSet: TDataSet);

/// <summary>

/// You must call InitializeDictionary each time you as-

sign the

/// DataSet property of the grid before you can use Get-

Field

/// </summary>

function GetField(const Name: string): TField;

end;

This class is not very complicated. It uses a generic TDictionary<key,value> to implement the GetField method. This can be seen in the implementation of this class, shown here:

{ TDBGrid }

constructor TEasyReaderDBGrid.Create(AOwner: TComponent);

begin

inherited;

FDict := TDictionary<string, TField>.Create;

end;

destructor TEasyReaderDBGrid.Destroy;

begin

FDict.Free;

inherited;

end;

function TEasyReaderDBGrid.GetField(const Name: string):

TField;

begin

Result := FDict.Items[Name];

end;

procedure TEasyReaderDBGrid.InitializeDictionary(DataSet:

TDataSet);

var

MAGAZINE

12

This process of extending an existing class, especially one that is notTObject, is used extensively by the visual component library (VCL),and to a lesser extent in the runtime library (RTL). Importantly, it is atechnique that you can use to create your own custom classes, onesthat inherit the power of an existing class, and which extend that classto add additional features. These features might include new proper-ties, additional methods, or alternative behaviors for methods inheritedfrom the ancestor class.

Overall, the VCL is a remarkable and rich component library. None-theless, it is not uncommon, especially with seasoned developers, towant to extend existing classes of the VCL or RTL to add custom capabilities.

In this article I am going to discuss two different, though not entirelydissimilar, techniques for creating a new class based on an existingVCL component. In most cases, these techniques can also be usedto extend any component, whether created by you or your develop-ment team or a third party. Towards the end of this article I will compare these two techniques by discussing the particular strengthsof each approach.

The Traditional MethodMost developers who sub-class components of the VCL do so by declaring that class as a descendant of the existing component, followed by compiling that class into a runtime package which theyinstall in Delphi. I am going to demonstrate this technique by creatinga component that extends the TDBGrid class, adding a handy featurefor reading data from it's underlying TDataSet. This feature is similar toone that I demonstrated during my talk "More Cool ClientDataSetTricks" during last December's SDE+ in Papendal.

This sub-classed grid exposes a GetField method, which returns aTField associated with the current record of the data set being displayed by the grid based on the name of the underlying datasetfield. This new class also includes an InitializeDictionary method whichmust be called at least once after the grid has been associated with adataset, but before the first call to GetField.

Note: The code shown in this article can be found at http://www.JensenDataSystems.com/subclassing.zip.

Here is the declaration of this new class, named TEasyReaderDBGrid:

DELPHI

Field: TField;

begin

for Field in DataSet.Fields do

FDict.Add(Field.FieldName, Field);

end;

All we need to do to make this component available on the componentpalette is to create a design time package, add this component's unitto the package, make a call to RegisterComponents from a Registerprocedure, and then install this new package.

I've added the forward declaration and implementation of the Regis-ter method to the same unit in which the TEasyReaderDBGrid classis declared, adding this new component to the Samples page of theTool Palette. Finally, here is the source of the design time package:

package EasyReaderDBGrid;

{$R *.res}

{$IFDEF IMPLICITBUILDING This IFDEF should not be used by

users}

{$ALIGN 8}

{$ASSERTIONS ON}

{$BOOLEVAL OFF}

{$DEBUGINFO ON}

{$EXTENDEDSYNTAX ON}

{$IMPORTEDDATA ON}

{$IOCHECKS ON}

{$LOCALSYMBOLS ON}

{$LONGSTRINGS ON}

{$OPENSTRINGS ON}

{$OPTIMIZATION OFF}

{$OVERFLOWCHECKS OFF}

{$RANGECHECKS OFF}

{$REFERENCEINFO ON}

{$SAFEDIVIDE OFF}

{$STACKFRAMES ON}

{$TYPEDADDRESS OFF}

{$VARSTRINGCHECKS ON}

{$WRITEABLECONST OFF}

{$MINENUMSIZE 1}

{$IMAGEBASE $400000}

{$DEFINE DEBUG}

{$ENDIF IMPLICITBUILDING}

{$DESCRIPTION 'Runtime package for TEasyReaderDBGrid'}

{$DESIGNONLY}

{$IMPLICITBUILD ON}

requires

rtl,

vcl,

dbrtl,

vcldb;

contains

Traditionalu in 'Traditionalu.pas';

end.

Once we compile and install this new design time package, the newcomponent, TEasyReaderDBGrid appears on the Samples page ofthe Tool Palette, as shown in Figure 1.

Fig. 1: A traditionally sub-classed component appears on the ToolPalette

Figure 2 shows a VCL Forms application on which an instance of theTEasyReaderDBGrid class has been placed at design time. In this figure a call to GetField has been made from the OnClick event handler of a button, shown here:

procedure TForm1.Button1Click(Sender: TObject);

begin

ShowMessage(EasyReaderDBGrid1.GetField('CustNo').As-

String);

end;

Fig. 2: The GetField method of the TEasyReaderDBGrid component returns a TField associated the grid's TDataSet

The Interceptor MethodUnlike the traditional method, which involves adding a component tothe component palette, the interceptor method "intercepts" the nameof the existing VCL component, mapping it to a different class. Consider the form shown in Figure 3.

Fig. 3: A VCL Forms application using a class that interceptsTDBGrid

The form in Figure 3 looks and behaves like that shown in Figure 2. Thedifference is that the grid that appears in Figure 3 is not a TEasyReaderDBGrid. Instead, the grid is actually an instance of the TDBGridclass. This class, however, is intercepted and extended, giving theTDBGrid class the methods necessary to support the features of theTEasyReaderDBGrid class. There are two general approaches to class interception. One is to intercept the class within the module where the extended class is

magazine voor software development 13

DELPHI

MAGAZINE

14

used. This approach is shown in the following type declaration:

type

TDBGrid = class(Vcl.DBGrids.TDBGrid)

private

{ Private declarations }

FDict: TDictionary<string, TField>;

public

{ Public declarations }

constructor Create(AOwner: TComponent); override;

destructor Destroy; override;

procedure InitializeDictionary(DataSet: TDataSet);

/// <summary>

/// You must call InitializeDictionary each time you

assign the

/// DataSet property of the grid before you can use Get-

Field

/// </summary>

function GetField(const Name: string): TField;

end;

TForm1 = class(TForm)

ClientDataSet1: TClientDataSet;

DataSource1: TDataSource;

Button1: TButton;

DBGrid1: TDBGrid;

procedure Button1Click(Sender: TObject);

procedure FormCreate(Sender: TObject);

end;

Alternatively, the interceptor class can be declared in its own unit. In that case, all you need to do is ensure that the unit in which the interceptor class is declared appears later in the uses clause than theunit of the class that is being extended. Here is an example of how theinterface section of an interceptor unit might look (the implementationis identical to that shown earlier for the TEasyReaderDBGrid class):

unit Interceptoru;

interface

uses System.Classes, Vcl.Grids, Vcl.DBGrids,

System.Generics.Collections, Data.DB;

type

TDBGrid = class(Vcl.DBGrids.TDBGrid)

private

{ Private declarations }

FDict: TDictionary<string, TField>;

public

{ Public declarations }

constructor Create(AOwner: TComponent); override;

destructor Destroy; override;

procedure InitializeDictionary(DataSet: TDataSet);

/// <summary>

/// You must call InitializeDictionary each time you

assign the

/// DataSet property of the grid before you can use Get-

Field

/// </summary>

function GetField(const Name: string): TField;

end;

When using an interceptor unit, I generally find it necessary to document the placement of the interceptor unit in the uses clause, asshown here:

unit MainformIu;

interface

uses

Winapi.Windows, Winapi.Messages, System.SysUtils,

System.Variants, System.Classes, Vcl.Graphics,

Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids,

Vcl.DBGrids, system.Generics.Collections, Data.DB,

Vcl.StdCtrls,Datasnap.DBClient,

Interceptoru; //This unit must appear later in this

//uses clause than the Vcl.DBGrids unit

type

TForm1 = class(TForm)

ClientDataSet1: TClientDataSet;

DataSource1: TDataSource;

Button1: TButton;

DBGrid1: TDBGrid;

procedure Button1Click(Sender: TObject);

procedure FormCreate(Sender: TObject);

end;

The real difference in implementation between the traditional methodand the interceptor method is that your code looks as though you areusing the class that you sub-classed, as opposed to the sub-class itself. This can be seen in the following event handler, which is similarto the OnClick event handler for the button shown earlier in this article.

procedure TForm1.Button1Click(Sender: TObject);

begin

ShowMessage(DBGrid1.GetField('CustNo').AsString);

end;

Comparing These Two MethodsWhile the end result of these two approaches is identical, there aresignificant differences. These differences make each of these mechanisms better suited for some uses over the other. I'll begin byconsidering the advantages of the traditional approach.

Advantage of the Traditional ApproachThe primary advantage of the traditional approach is that your sub-classed component can appear in the Tool Palette. Having thecomponent in the Tool Palette provides two benefits. First, any published properties that you add to your sub-classed component willappear in the Object Inspector at design time. Second, once you'veplaced the component onto your module from the Tool Palette, theunit in which your component is defined will be added to your interfacesection automatically the next time you save or compile your project.

Both of these benefits come down to convenience. Traditionally sub-classed components are easier to use.

Advantages of the Interceptor ApproachWhile the interceptor approach has the drawback that it is somewhatmore complicated to use, it also introduces benefits that make it a powerful alternative. To begin with, creating a interceptor class takesless time. There is no need to create a design time package and a design time package does not need to be installed.

Not needing a design time package actually makes interceptor classes easier to share with a development team. Using the traditio-nal approach, you need to provide each of the developers who will beworking on the project with access to the package, which they willneed to install into their copy of Delphi. When using an interceptor

DELPHI

magazine voor software development 15

class, all you need to do is add the interceptor class unit into a directory on your library search path, and it will just work. Alternatively, you can make the interceptor unit a unit of your project,again making any classes defined in it immediately available to anyunit that uses the interceptor unit.

Another advantage of an interceptor class is that is makes it remarkably easy to extend an existing class when you want to addonly one or two new features. Furthermore, when you declare your interceptor class directly in the unit from which it will be used, you cancustomize each instance of the ancestor class for that module. Forexample, you might want to add an additional method to a TListBoxinterceptor on a given form. If you have a second form that also needsa modified TListBox, but with a different custom method, no problem.Create a different interceptor class for each form and you are done.

Finally, and what I think is absolutely the best advantage of intercep-tor classes is that it lets you make customizations to a componentssub-classes. For example, imagine that you want to add one or morecustom properties to the individual menu items of a TMainMenu. This can be done very easily by creating an interceptor class for TMenuItem. After that, all of the menu items you add to your mainmenu will have those properties. Granted, you can only access thoseproperties at runtime, but that is just a detail.

Here is a simple example of a TMenuItem interceptor type declarationthat, if added to a unit prior to the TForm declaration, adds a MyInteger runtime property to any menu item appearing on that form.By comparison, if you use the traditional approach, you would have toactually sub-class TMainMenu and implement an extended version ofTMenuItem from within the owner class.

typeTMenuItem = class(Vcl.Menus.TMenuItem)strict private

FMyInteger: Integer;public

property MyInteger: Integer read FMyInteger write FMyIn-teger;

end;

SummarySub-classing existing classes of the VCL (or other libraries) is a powerful tool that every Delphi developer should take advantage of. Inthis article I have looked at the two primary mechanisms for sub-classing existing components. Each of these approaches have theirstrengths, making each best suited for some applications over theother. •

Cary Jensen

Cary Jensen is the bestselling

author of more than 20 books on

software development, including

Delphi in Depth: ClientDataSets,

and winner of the 2002 and 2003

Delphi Informant Reader's Choice

Award for Best Training. A frequent

speaker at conferences, workshops, and seminars throughout

much of the world, he is widely regarded for his self-effacing

humor and practical approaches to complex issues. Cary's com-

pany Web site is at: http://www.JensenDataSystems.com. Cary

has a Ph.D. from Rice University in Human Factors Psychology,

specializing in human-computer interaction.

Windows Azure Mobile Services ExamplesZoals Didier Caron eerder in ons magazine al schrijft. Windows Azure Mobile Services maken het eenvoudiger omsnel mobiele applicaties te maken met Windows Azure als backend. Dat is dan niet beperkt tot Windows Phone 8 enWindows 8, ook IOS en Android behoren tot de ondersteunde platforms.

Nick Harris (@cloudnick) heeft ook nog eensallerhande voorbeelden beschikbaar gesteld.Met deze voorbeelden zijn de mogelijkhedenvan Windows Azure Mobile Services onbegrensd.

Geolocation sample end to end using Windows Azure Mobile Services

http://code.msdn.microsoft.com/windowsapps/Geolocation-sample-end-to-5d9ee245

Enqueue and Dequeue messages withWindows Azure Mobile Services and Services Bus

http://code.msdn.microsoft.com/windowsapps/Enqueue-and-Dequeue-e9429caa

Capture, Store and Email app Feedbackusing Windows Azure Mobile Services

http://code.msdn.microsoft.com/Capture-Store-and-Email-34005240

Upload File to Windows Azure Blob Storage using Windows Azure Mobile Services

http://code.msdn.microsoft.com/windowsapps/Upload-File-to-Windows-c9169190

Create a Game Leaderboard using Windows Azure Mobile Services

http://code.msdn.microsoft.com/windowsapps/Adding-a-Leaderboard-to-1f9d216d •

GENERAL

Kijk eens in de spiegel en vraag jezelf eens af wanneer je voor hetlaatst aan een oplossing hebt (mee)gewerkt die uitblonk in simplisme.Tot mijn spijt en ongenoegen moet ik toegeven dat veel projecten waarik in het verleden aan mee heb gewerkt uiteindelijk veel complexer zijngeworden dan ik voor ogen had. Dat is jammer, want als we een oplossing echt simpel kunnen maken, snapt iedereen wat het doet enis het voor de mensen die het moeten maken en beheren ook veelmakkelijker te begrijpen hoe het dat doet. Kortom, minder ontwikkel-kosten, minder beheerkosten, tel uit je winst!

EssentieIk hoor nu een aantal mensen denken: “dan moet je Agile werken.”Ja, Agile kan zeker helpen bij het verlagen van ontwikkelkosten. Hetkan wellicht ook helpen bij het simpel houden van onderdelen van eenoplossing. Veel van de projecten die ik gedaan heb zijn echter metScrum/Agile aangevlogen, dus daar ligt de kern van het probleem helemaal niet. Als het niet aan de projectorganisatie ligt, is de vraagwaar het dan wel aan ligt. Het antwoord zit misschien in een projectwaar ik nu mee bezig ben, hoewel ik me bewust ben dat dit achterafook weer een illusie kan zijn. Waarom denk ik dat dit project de potentie heeft om echt tot het beoogde simplisme te komen? Omdatwe helemaal terug zijn gegaan naar de tekentafel en zelfs daarvoor. In het huidige landschap zitten een aantal applicaties die een specifiekproces ondersteunen. Als we echter kijken naar de essentie van aldeze systemen blijkt dat ze eigenlijk heel veel gemeen hebben.

Sterker nog, in essentie doen ze hetzelfde, ze wijken alleen af op eenaantal specifieke punten. Wat we dus moesten doen is kijken of weeen systeem kunnen maken die de essentie vat en alleen uitzonde-ringen maakt als dat echt nodig is of het mogelijk maakt om voor deuitzonderingen uitstapjes te maken naar andere systemen, die specifiek voor de uitzondering gemaakt zijn en daardoor ook terug-gebracht tot hun essentie.

SharePoint AppsDat ik niet helemaal alleen ben in de visie dat zaken eenvoudiger enstabieler zijn als je ze terugbrengt naar hun essentie zie je aan Apps inSharePoint 2013. Kort door de bocht zijn SharePoint Apps websitesdie niet meer in SharePoint draaien. Server-side in SharePoint programmeren is uit den boze. Alle interactie met SharePoint doe je viade standaard aanwezige webservices op de lists, document librariesenz. In SharePoint doe je dus alleen nog maar aan configuratie.

Hiermee wordt SharePoint teruggebracht tot de essentie van het platform en kun je dus niet meer met custom code SharePoint in problemen brengen. Dat maakt SharePoint zelf (als het goed is) beterte beheren voor de gemiddelde beheerder. Voor de custom stukkengaan we weer terug naar regulier web development en dat kan in ASP.NET (WebForms), ASP.NET MVC, PHP of welke andere technologie dan ook. Als ontwikkelaar is dat eigenlijk alleen maar prettig. Je hebt minder restricties en kunt werken met je favoriete technologie, in plaats van dat je in .NET WebParts moet maken opeen hele specifieke manier. Je kunt je als ontwikkelaar dus richten opde essentie, niet op de restricties die SharePoint je oplegt.

Walhalla?Net als bij mijn eigen project zal de nieuwe SharePoint aanpak zichnog moeten bewijzen. Het kan zomaar dat we nieuwe problemen krijgen die we nog niet kunnen overzien. In het geval van SharePointApps bijvoorbeeld wordt beveiliging wel een heikel punt. Aangezienniet zoals een WebPart op de SharePoint server draait, maar mogelijk op een webserver een ander domein, is er geen gedeeldebeveiligingscontext. Je zult dus in je App zelf zorg moeten dragen datiemand niet bij spullen kan waar hij/zij niet bij mag komen, geheel losvan de rechten die je in SharePoint uitdeelt. •

Einstein zei ooit eens: “Everything should bemade as simple as possible, but not simpler.” Ondanks onze beste intenties hebben we er in de IT een handje van om oplossingen te complex te maken. Hoe kunnen we dat voorkomen?

Michiel van Otegem

Kort door de bocht zijn SharePoint Apps websites die niet meer in SharePoint draaien

Je kunt je als ontwikkelaar richten op de essentie, niet op de restrictiesdie SharePoint je oplegt

Back to Basic

magazine voor software development 17

MOBILE

Android is een platform dat naast de reguliere Dalvik virtual machinedraait op je telefoon. In [figuur 1] is schematisch weergegeven hoe hetMono for Android platform eruit ziet en wat de relatie is ten opzichtevan de Dalvik omgeving op Android.

Fig. 1: Mono for Android architectuur

In een Mono for Android app werk je vanuit je C# code nauw samenmet de Android/Dalvik omgeving. Die samenwerking komt tot standdoordat je bijvoorbeeld gebruik gaat maken van de Activity class omschermen in je app te implementeren. Op het moment dat je eennieuwe instantie maakt van een class, die afkomstig is uit een Androidof Java namespace, dan maak je een instantie van een zogenaamdeMono calleable wrapper. Bij het aanmaken van een instantie van eendergelijke wrapper, wordt er in de Dalvik virtual machine eenzelfde object in het leven geroepen als die je in de Mono omgeving hebt geïnstantieerd. Alle methodes en properties die je aantreft op het object in de Mono omgeving zijn gekoppeld via de Java Native Inter-face aan methodes en properties op het Java object dat in de Dalvikomgeving leeft. Gegevens die je doorgeeft aan een methode op eenMono calleable wrapper, worden door de Java Native Interface getransporteerd naar de Dalvik omgeving.

Vanuit de Dalvik omgeving wordt er ook gebruik gemaakt van componenten die je hebt geschreven in C#/Mono. Om bijvoorbeeld jeapp te starten moet de Dalvik omgeving in staat zijn om de activityclasses, die je hebt geschreven voor je app, te kunnen instantiëren enaanroepen. Om dit mogelijk te maken worden er Android calleablewrappers gegenereerd voor je app. Deze lijken heel veel op de Monocallable wrappers, alleen hier wordt er gebruik gemaakt van een Monofor Android runtime bridge. Dit is een verzameling functionaliteit welkede Mono variant vormt van de Java Native Interface.

Mono en Android, een prima koppel

Deze vraag en nog een heleboel andere vragen komen regelmatigvoorbij wanneer ik ontwikkelaars vraag of ze al eens met Mono for Android hebben gewerkt. De ontwikkelaars die ik heb gesproken overMono for Android zijn te verdelen in twee groepen. Er is een groep dieerg geïnteresseerd is in de mogelijkheden en er direct mee wil begin-nen te werken. De tweede groep is vooral heel kritisch. Mono for Android is bijvoorbeeld niet native en het zou slechter werken dan deJava virtual machine die je normaal gesproken gebruikt.In dit artikel laat ik zien wat Mono for Android is en waarom je Monofor Android zeker een keer moet proberen als je een Android app gaatbouwen.

Het .NET platform voor Android telefoonsMono for Android is in essentie .NET voor je Android toestel. Het biedteen manier om apps die in C# zijn geprogrammeerd te draaien op Android. Om dit alles mogelijk te maken is door Xamarin een specialeversie van het Mono framework geschreven voor Android. Oorspron-kelijk is Mono een framework dat is ontwikkeld om de functionaliteit inhet .NET framework beschikbaar te maken voor andere platformszoals Linux en Mac OS X. Een aantal open source ontwikkelaars onderde leiding van Miguel De Icaza hebben in de afgelopen jaren keihardgewerkt aan het porten/namaken van diverse classes uit het .NET framework, zodat de applicaties die je schrijft op basis van .NET ookop Linux en Mac kunnen worden uitgevoerd. Op basis van het werkdat is gedaan voor Mono, is door Xamarin het product Mono for Android gemaakt. Ze hebben het Mono platform omgebouwd zodathet op een ARM processor kan draaien en hebben daar vervolgensalle libraries van Android tegenaan geplakt. Dit resulteert erin dat jeeen app kan ontwikkelen die aan de ene kant alle mogelijkheden vanhet Android platform kan gebruiken en aan de andere kant alle baseclass libraries van .NET tot zijn beschikking heeft.Je hoeft voor het maken van een app op deze manier maar twee dingen te weten, namelijk welke classes zijn er in Android beschikbaarom een app te bouwen, deze zul je nu namelijk ook beschikbaar hebben in C#, en daarnaast moet je weten hoe .NET/C# werkt. Vooraldat laatste zal geen enkel probleem vormen voor een gemiddelde.NET ontwikkelaar. Zoals je zult merken, tijdens het ontwikkelen van jeeerste app, hoef je dus geen Java te kunnen programmeren om Android apps te bouwen.

Twee samenwerkende platformenOndanks dat je geen Java kennis nodig hebt wanneer je normale appsbouwt, is het toch goed om te weten hoe Mono for Android is gemaakt en wat de relatie van dit framework is ten opzichte van deDalvik Java virtual machine die apps draait op Android. Mono for

Willem Meints

Toen ik de kans kreeg om, inmiddels meer dan twee jaar geleden, voor het eerst Mono apps tebouwen op Android, wist ik niet waar ik aan begon. Het is namelijk nogal verrassend dat je metC#, in een omgeving die volledig is geschreven in Java, een mobile app kunt bouwen. Waaromzou je nou juist C# gaan programmeren op een Android telefoon?

MAGAZINE

18

MOBILE

Het slaan van de brug tussen de Dalvik virtuele machine en de Monovirtuele machine zorgt voor wat overhead bij het draaien van je app.Wanneer je namelijk van een class, uit de Android libraries, een instantie aanmaakt dan krijg je twee objecten. Deze moeten beideworden beheerd. Ook is het zo, dat wanneer je een methode aanroept op een dergelijk component, er gegevens moeten wordengekopieerd van de Mono omgeving naar de Dalvik omgeving en terug.Voor valuetypes geldt hierbij dat deze gekopieerd worden. Voor reference types wordt er gebruik gemaakt van uitwisseling van geheugenadressen. Hoewel het lijkt dat dit heel traag is, zal je in depraktijk hier niet heel veel last van hebben. De Java Native Interface ende Mono for Android runtime voeren deze kopieerslagen zeer efficiënt uit.

Al het bekende van .NETDe brug tussen Mono en Java levert gelukkig niet alleen overhead op,het maakt ook een aantal hele interessante scenario’s mogelijk in jeapp. Je hebt namelijk door het gebruik van Mono for Android nagenoeg alle classes uit het .NET framework beschikbaar in je app.Als je al eerder met .NET hebt gewerkt is het een prettige gedachte datje vrijwel direct resultaat boekt en niet veel hoeft bij te leren om een appte bouwen.

Om bijvoorbeeld te communiceren met webservices kun je gebruikmaken van WCF (Windows Communication Foundation), waardoor jemet enkele muisklikken al toegang hebt tot SOAP services. Je kunt namelijk in een Mono for Android app project in Visual Studio, een service reference toevoegen op dezelfde manier als dat je dat zoudoen voor een reguliere .NET applicatie.Verder heb je LINQ en PLINQ beschikbaar om met weinig code tochheel snel en efficient met verzamelingen gegevens te werken. Ditmaakt het werken met webservices in je app nog sneller en slimmer,waardoor je eerder een app kan laten zien aan je opdrachtgever.Het is de moeite waard om hier ook TPL (Task Parallel Library) te vermelden. Met de set classes uit het .NET framework kun je eenvoudig taken asynchroon of parallel laten uitvoeren. Middels deTPL componenten kun je in je Android app bijvoorbeeld de commu-nicatie met een webservice asynchroon maken, waardoor de user interface van je app vlot blijft reageren op de invoer van de gebruiker.Dit levert een prettige gebruikerservaring, zonder dat je daar heel veelvoor hoeft te doen als ontwikkelaar.

Op dit moment is er gekozen om alleen de classes die je ook in Silverlight 3 aantreft, beschikbaar te stellen binnen het Mono for An-droid platform. Dit is gedaan, omdat in Silverlight 3 COM en het Wind-ows register niet zijn geimplementeerd, deze zijn namelijk alleenbruikbaar op Windows. De ontwikkelaars vonden het dan ook nietnuttig om deze over te zetten naar niet Windows omgevingen. Op dit moment komen er steeds meer features uit het .NET 4.5 beschikbaar, zoals het async en await keyword. Xamarin heeft er voorgekozen om af te stappen van Silverlight als basis en is overgestaptop het ondersteunen van het volledige .NET framework, behalve deondersteuning voor System.Configuration, COM en het Windows register. Mede doordat Microsoft steeds meer open source beschikbaar maakt, zal je merken dat Mono for Android steeds uitgebreider wordt.

De kracht van Java libraries gebruikenNaast dat je de beschikking hebt over de mogelijkheden van het .NETframework, heb je ook de mogelijkheid om bestaande Java code teintegreren in je app. Hierdoor kun je ook libraries die oorspronkelijk zijngeschreven voor native Android apps, ook gebruiken in je Mono forAndroid app.Een van de krachtigste extra’s die het Mono for Android platform aanbiedt is namelijk het kunnen binden van Java libraries. De bindingtechniek die hiervoor gebruikt wordt is dezelfde die wordt toegepast

door Xamarin in de platform componenten van Mono for Android.Er zijn op Android al een groot aantal libraries uitgebracht die allerleizaken voor je regelen. Een van de meest bekende is de ActionBarSherlock library. Met de ActionBar Sherlock library kun je op een breedscala aan toestellen gebruik maken van de ActionBar feature, die normaal alleen voor Android 3.0 en hoger beschikbaar is. De Action-Bar is een balk bovenaan het scherm, waarmee je bepaalde functionaliteiten van de app snel beschikbaar hebt, zoals een optiesmenu of een zoekbutton. Aangezien de ActionBar een van de meesttoegepaste elementen in een Android app is, is het prettig om te wetendat je niet voor elke oude telefoon dit onderdeel volledig opnieuw moetuitprogrammeren. Voor C# ontwikkelaars is de ActionBar Sherlock library niet zomaarbeschikbaar. Er is geen port voor gemaakt in C#. Dat houdt je als ontwikkelaar echter niet tegen om hem toch te gebruiken. Je kunt namelijk voor deze library prima een binding genereren. Het resultaathiervan is een .NET assembly waar je een referentie naar kan zettenvanuit je Mono for Android app project.Xamarin heeft een speciaal projecttype beschikbaar in Visual Studiovoor het maken van een Java library binding. Bij het aanmaken van eennieuw project in Visual Studio kun je dit type vinden onder de sectieMono for Android (Zie figuur 2).

Fig. 2:New project dialoogvenster

Na het aanmaken van een project op basis van dit projecttype, krijg jeeen Mono for Android project met een drietal mappen daarin. Er iseen map Jars aangemaakt in het project, in deze map kun je de jar filesof project library zip files plaatsen met de Java code waar je tegen wiltgaan binden. Het verschil tussen deze beide zal ik verderop in dezesectie toelichten. De tweede map, is de map Transforms. In deze map vind je een aantal bestanden om mappings aan te leggen van de originale JavaAPI naar de nieuw te genereren C# API. Hiermee kun je bijvoorbeeldde namespaces die worden gegenereerd aanpassen, of de zicht-baarheid van types veranderen van public naar private of andersom.

Fig. 3: Projectstructuur Java binding library

magazine voor software development 19

MOBILE

MAGAZINE

20

De derde map is de Additions map. In deze map kun je eventuele toevoegingen voor je binding plaatsen. Hierbij moet je denken aanextra helper methods die je in C# geschreven hebt om beter met debinding te kunnen werken. In figuur 3 is te zien hoe de project-structuur eruit ziet zoals die door Visual Studio wordt gegenereerd.

De basis van een Java binding libraryDe kern van een C# binding voor Mono for Android is een JAR file ofeen project library. Op basis hiervan worden alle C# classes gegenereerd, die je vervolgens met transforms kan mappen naar eenvorm die prettig voor je werkt. Op het Android platform kun je op tweemanieren elementen uit je app hergebruiken in andere apps. Je kunteen JAR file maken, die je toevoegt aan je app. De andere manier isom een project library te bouwen. Het belangrijkste verschil tussen het gebruik van een project library eneen JAR file zit hem in het gebruik van resources. Naast gecompi-leerde code vind je in een android app ook XML files die de layout vanschermen beschrijven, bestanden voor het vertalen van teksten, bestanden die uitklapmenu’s beschrijven en allerlei andere bestandendie je nodig hebt om de styling van je app aan te passen. Dit soortbestanden staan bekend als de resources van een Android app. Alsje een library bouwt die alleen bestaat uit gecompileerde code dankun je op Android het beste gebruik maken van een JAR library for-maat. Dit is hetzelfde formaat dat ook wordt voor traditionele Java applicaties. Maak je een library waarbij je gebruik maakt van bijvoor-beeld vertalingen of layout bestanden dan moet je een Android projectlibrary maken. In Mono for Android kun je voor beide soorten librariesbindings genereren. Als je een JAR file hebt die je zou willen gebrui-ken, dan kun je hiervoor bindings genereren door de JAR file toe tevoegen aan het Java Bindings Library project in Visual Studio. Als jebindings wilt genereren van een Android project library, dan kun je deinhoud van de Android project library zippen en die toevoegen aan hetVisual Studio project. Op basis van de toegevoegde libraries worden, als je het Java Bindings project in Visual Studio compileert, automatisch de benodigde Mono calleable wrappers gegenereerd, zodat je gebruikkan maken van de componenten uit de gekozen libraries.

Onderdelen van de binding aanpassenZodra je in Visual Studio het Java bindings project hebt gecompileerdworden er C# classes voor je gegenereerd die samen de binding vormen voor de JAR file of het Android library project. In bijna alle gevallen zal je merken dat de binding niet direct compileert of niet helemaal netjes in elkaar zit. Dat komt omdat .NET/C# en Java flinkverschillen van elkaar. Allebei hebben ze krulhaken en puntkomma’s,maar hierna komen toch wel een aantal verschillen voorbij, waar je direct last van hebt bij het maken van je bindings. Het begint met denamespaces die worden gebruikt in Java en .NET. In Java is men gewend om in de vorm com.somecompany.library.funkynamespacesde namespaces in te delen. In .NET is dit allemaal toch net even an-ders opgezet. Zo worden er hoofdletters gebruikt in de naamgeving enbegint een namespace eigenlijk nooit met com.somecompany, hoog-uit met de naam van het bedrijf. Je kan dergelijke namespace ver-schillen prima overbruggen, door in de metadata.xml file een mappingop te nemen. In voorbeeld 1 zie je hoe een mapping eruit kan zien.

<remove-node path="/api/package[@name=

'com.actionbarsherlock.internal.widget']"/>

<attr path="/api/package[@name='com.actionbarsherlock.wid-

get']"

name="managedName">ActionBar_Sherlock.Widget</attr>

Voorbeeld 1: Mapping specificatie

De eerste regel beschrijft het verwijderen van een node uit de API. Jekan met een dergelijke operatie, complete namespaces, maar ook

specifieke velden of methodes verbergen in de gegenereerde C# library. De originele library blijft wel ongemoeid, je kan er alleen nietmeer bij vanuit je C# code. De tweede regel in het voorbeeld met hetattr element laat zien hoe je attributen van een element uit de JavaAPI kan aanpassen. Hiermee kun je bijvoorbeeld de naam van eenclass of namespace aanpassen, zodat deze een beter bruikbare naamkrijgt in C#. Dat is niet het enige, je kan hiermee ook de zichtbaarheidvan een Java type aanpassen. Vooral het aanpassen van zichtbaarheidvan classes zal je veelvuldig nodig hebben, omdat je in Java publicclasses van protected classes mag laten afleiden. De binding genera-tor in Visual Studio zal dit voor de gegenereerde C# binding classesook proberen, maar dat lukt niet, omdat je in C# deze constructie nietmag bouwen. De oplossing op dat moment is de zichtbaarheid vanhet base type in de mapping file aanpassen, zodat deze ook publicwordt. Ik heb bewust niet de volledige beschrijving in dit artikel opge-nomen van de file uit de Transforms map opgenomen. Voor een vol-lediger beschrijving kun je het beste naar de Xamarin website(http://docs.xamarin.com/Android/Guides/Advanced_Topics/Binding_API_Metadata_Reference) surfen.

De bindings gebruiken in je appHet java bindings project levert een .NET assembly op, met daarin C# types die de componenten uit de gekoppelde Java library representeren. Bij het gebruik van een binding op basis van een JARfile is het noodzakelijk om de JAR file die als basis is gebruikt, op tenemen in je Mono for Android app project. Het buildproces heeft dezenamelijk weer nodig om de Java code en C# code goed in elkaar tecompileren. Voor een binding op basis van een Android library projectis dat niet nodig, hierbij zit de zip met de benodigde files in de bindingassembly verpakt. In figuur 4 is de projectstructuur van een app weer-gegeven die gebruik maakt van een Java bindings library.

Fig. 4: Projectstructuur van app met Java bindings

In dit voorbeeld is gebruik gemaakt van de ActionBarSherlock librarydie middels een Java bindings library beschikbaar is gemaakt voorC#/Mono. Omdat de bindings library een .NET assembly is, kun je eenreferentie zetten naar de library (ActionBarSherlockBinding). Er is gebruik gemaakt van een extra JAR file vanuit de bindings library, namelijk android-support-v4.jar. Deze is als extra bestand opgenomen in het app project.

Niet alleen omdat het kanMono for Android is door de mix van Java en Mono zeer uitgebreid enflexibel. Werk je als ontwikkelaar in een omgeving waarbij je niet

MOBILE

Sinds enige tijd ben ik in het bezit van een Surface RT (inmiddels te koop in de Neder-landse online Microsoft Store, Media Markten TabletCenter). Ik vind het echt een geweldig apparaat. Het is een typische kitchen table device, behalve dan dat hijwel gepersonaliseerd is natuurlijk. Door devele apps in de store gebruik ik hem ‘s ochtends veel om eerst de verschillendenieuws -zaken op te pikken: NU.nl, NOS, Telegraaf, mail etc. Ook om effe een beetjete internetten en te Facebooken is het een geweldig apparaat.

Veel criticasters komen dan meteen met opmerkin-gen: “ik kan applicatie XYZ niet installeren”. En mijndeveloper vrienden zeggen dan gelijk, kan je er ookop ontwikkelen. Ja, wat is het probleem? Dat kun jetoch ook niet op een iPad of op een Android device?Daar moet je app’s downloaden vanuit de store enandere apps kunnen niet.

Misschien zit daar wel het marketing probleem hoor.Een Microsoft Surface RT of een ARM device van eenconcurrent beschikken over Windows RT. Het feit dater Windows gebruikt wordt, geeft het vermoeden dater meer kan dan werkelijk het geval is. Ook de aanwezige Desktop tile doet vermoeden dat er meerkan.

Ook de gedachte dat het een Enterprise apparaat zouzijn, kloppen niet. Tenslotte een Surface RT of Windows RT device kan niet gekoppeld worden aaneen domein. Ook Group policies zijn niet mogelijkmet Windows RT. Ook aan de licentie kant is er nogeen haakje. Een Surface RT wordt standaard gele-verd met Microsoft Office 2013. Dit is een Home/Student versie. Dat betekent, dat je er geen com-mercieel werk mee van uitvoeren. Op zich allemaalniet erg, want een iPad hang je ook niet in het domein ;-)

Als je meer wilt en wilt kunnen, dan zou een SurfacePro een oplossing kunnen zijn. Deze is uitgerust meteen i5 en beschikt over 4 Gb geheugen. Redelijk

voldoende voor de meeste toepassingen. Er zijn tweeharddisk varianten 64 Gb en 128 Gb.Dat lijkt niet veelmaar we hebben tegenwoordig toch het meeste inde Cloud staan. Toch? Ik heb een 64 Gb variant en ikheb nog 7.5 Gb over. Ik heb Visual Studio, MicrosoftOffice en WP8 SDK geïnstalleerd. Op een Surface Prokun je wel desktop apps installeren en aan een domain toevoegen etc.

Maar zijn het dan wel dezelfde apparaten? Nou nietecht eigenlijk. Ze zien er op het eerste gezicht gelijkuit, maar de Pro is duidelijk dikker. Grotendeels veroorzaakt door Core i5, want deze heeft nogal watkoeling nodig. Hoewel de Surface wel warm wordt,maar niet heet. De SD kaart gleuf zit op een andereplek dan op een RT. Een irritant dingetje is, dat deexterne display connector een ander type is. De RTgebruikt een HD video out port en de Pro gebruikteen mini Displayport. De batterij duur van de RT isruim 8+ uur en van de Pro is ongeveer 4 uur.Ook het scherm van beide is niet gelijk. De RT heeftin desktop mode een resolutie van 1366×768 en dePro heeft een 1920×1080 resolutie. Standaard merkje daar niet veel van, want het zoom level staat in-gesteld op 150%. De RT heeft 5 Touch point en dePro heeft het dubbele.

Ook wordt bij de Pro een Stylus geleverd, daarmeekun je tekenen zoals je dat op vorige Tablet laptopsdeed. Dit pennetje doet het dan ook niet op een RT.Ook dit is eigenlijk niet raar, want de RT heeft een

heel ander doel.Als we het dan toch over doelen hebben, volgens mijzit het zo. De Surface RT gebruik je zoals je een iPadgebruikt. Je installeert veel Windows Store apps engebruikt ook overwegend deze kant van de tablet.Heel af en toe als je Word/Excel/PowerPoint gebruikt,dan kom je op de desktop. In principe heb je daarminder te zoeken. De Surface Pro gebruik je als ietsmeer wilt dan alleen de Windows Store apps gebruiken. Je kunt er ‘oude’ desktop apps installerenen dat zit je aan de desktop kant van de tablet. Aangezien hij onhandig op je knieën ligt, kun je nietzo handig developpen als je op de bank voor de TVzit. Hoewel de i5 best snel is, willen wij developerstoch graag een i7 met veel geheugen. Om dat echt teontwikkelen heb je meer aan een Ultrabook mettouch scherm, zoals een Lenovo, Acer, Asus of HP.Deze kunnen veel zwaarder uitgevoerd worden metmeer geheugen en meer CPU.

Op dit moment heb ik Surface RT’s en een SurfacePro. Beide werken erg prettig. Voordat je overgaat totde aanschaf van een van beide, denk dan goed nawat je wil. Ook Enterprise of zakelijke gebruikersmoeten daar goed over nadenken.

magazine voor software development 21

Willem Meints

Willem Meints is consultant bij Info

Support voor het Professional De-

velopment Centre. Naast zijn werk

is hij een actief blogger waarbij hij

zich voornamelijk bezighoudt met

user interface technologieën als

ASP.NET, JavaScript en Mono for

Android.

Surface RT and Surface Pro

alleen voor Android, maar ook voor iPhone ontwikkelt dan zijn er zelfsnog meer redenen om gebruik te maken van de mogelijkheden vanMono for Android. Wanneer je namelijk de code voor je app strate-gisch opdeelt in logica voor de user interface en logica voor bijvoor-beeld communicatie met een cloudservice, dan kun je grotehoeveelheden code zonder aanpassing overnemen naar andere plat-formen zoals Monotouch of Windows Phone. Het resultaat van eendergelijke opzet is dat je goedkoper en sneller apps kan ontwikkelendie ook nog eens beter onderhoudbaar zijn. Wil je zelf ervaren hoe eenvoudig je Android apps kan ontwikkelen metC# en hoe goed de combinatie Java en Mono werkt, dan kun je eentrial versie van het Mono for Android framework downloaden vanafwww.xamarin.com. Deze website bevat ook een uitgebreide beschrijving van het framework en tientallen voorbeelden aan de waarmee je snel aan de slag kan. •

door Marcel Meijer

CLOUD

Maar als je een reeds bestaande website hebt, dan kun je die ookhosten op Windows Azure websites. Ook dan ben je met iets meerklikken up en running. Moet je in je website dan nog rekening houdenmet het hosten op Windows Azure? Nope, helemaal niet. Aan je web-site hoef je niets aan te passen en deze kan zo naar Windows Azure.En updates aan de website kun je dan gewoon deployen oftewel publishen zoals je dat ook op een ‘eigen’ webserver zou doen.

Oke, maar ik wil gebruik maken van Windows Azure storage of Windows Azure Service bus. Dat kan dan zeker niet? Jazeker wel,geen probleem. Uiteraard moet je in je applicatie dan wel iets aanpassen om volledig gebruik te maken van deze diensten. Ik heb dat zelf gebruikt voor de server kant van mijn nieuwe Windows8 en Windows Phone 8 applicatie. Met deze applicaties kun je de sessies van de SDN events evalueren en je waarde oordeel geven.

Het gaat hier niet om enorm veel data. Ik heb events en event hebbensessies en een sessie heeft een evaluatie. Er zijn ook geen hele moei-lijke relaties tussen tabellen. Dus typisch zo’n gevalletje voor WindowsAzure storage tables. Ook vanuit kosten oogpunt niet onbelangrijk.

Zoals gezegd, het gaan niet om veel data. Stel even 3 events maalmaximaal 20 sessies maal 150 bezoekers, dat blijft heel erg ruim onderde 100 Mb van de kleinste Windows Azure SQL Database. Het prijs-verschil tussen storage tables en SQL tabellen is dan best groot. (NBIk realiseer mij dat we soms SQL server functionaliteit gewoon nodighebben, maar ik denk ook wel dat we vaak te gauw grijpen naar ditmiddel. Deze data ontsluit ik voor de applicaties via een WebApi. Zodat deapps via een simpele REST interface de get en posts kunnen doenen JSON terug krijgen. En deze REST services zijn onderdeel van mijnWindows Azure Website.

Maar kan dat dan zomaar? Jazeker. Alles wat je nodig hebt, zijn dezetwee NuGet packages.

En deze code. De connectionstring naar de Windows Azure storagestaat dan in de Web.config.

Windows Azure Websites zijn erg handig om snel een website in de lucht te brengen. Je kuntdaarbij kiezen uit een gallery van producten. Deze gallery bestaat uit Blogs (WordPress ea),Content management systemen (DotNetNuke ea), Wiki’s etc. En als je door deze lijst heen loopt,dan zie je dat ze niet allemaal .NET based zijn. Sommige producten hebben SQL Server database nodig en sommige MySQL. Ook dat is geen probleem beide is mogelijk. Met eenpaar simpele klikken heb je zo een website in de lucht.

Marcel Meijer

Windows Azure Websites

MAGAZINE

22

CLOUD

De rest van je code is zoals je altijd met Windows Azure storage tablesomgaat. En mijn groeipad? Windows Azure Websites kun je ook scalen (meerdere instanties) en/of zwaardere machines van maken.

Stel je voor dat er straks toch een achtergrond proces bij komt, bijvoorbeeld om BI op de ingevoerde data te doen. Dan zou ik daareen WorkerRole voor nodig kunnen hebben. Dan kan ik de WindowsAzure Website zo ombouwen tot een Cloud Service. De setting van destorage zal dan verplaatsen van de web.config naar de Cloud Serviceconfiguration. Verder hoeft er in principe weinig te gebeuren aan deWeb Role. Uiteraard zal ik de Worker Role dan moeten uitwerken.

Windows Azure is niet een keurslijf waarin je vast zit, maar het kanmet je meegroeien. Je kunt klein beginnen en groeien naar immensehoogte. •

Marcel Meijer

Al meer dan 20 jaar begeeft deze

44-jarige zich in de wereld van de

ICT. Op dit moment houdt hij zich

voornamelijk bezig met Azure,

Cloud, C#, Software Ontwikkeling,

Architectuur in het algemeen en

Windows Phone 7. Ook is hij bezig met Biztalk en Sharepoint.

Hij werkt als Senior Solution Architect bij Qurius/Prodware. In zijn

vrije tijd is hij .NET track owner, eindredacteur en bestuurslid van

de SDN. Binnen de SDN is hij verantwoordelijk voor het regelen

van sprekers voor de SDN Events (SDE), het regelen/redigeren

van artikelen voor het SDN Magazine, mede verantwoordelijk voor

de eindredactie van de hardcopy en digitale magazines en de

inhoud van de SDN Conferences. Op 1 oktober 2010 werd hij

MVP.

magazine voor software development 23

� � � � � � � � � �

h

Mijn innovatieve geest denkt in Windows Azure. Windows Azure is het ontwikkelplatform in de cloud dat developers vrij baan geeft in hun denken.

Bouw en draai applicaties in de cloud. Lanceer applicaties in minuten, in plaats van uren. Programmeer

in meerdere talen en technologieën, zoals .NET, PHP en Java. Begin vandaag nog met innoveren.

2QJHKLQGHUG�GRRU�UHGXQGDQWLH��EDQGEUHHGWH�RI�GH�EHSHUNLQJHQ�YDQ�XZ�VHUYHUFRQÀJXUDWLH��

Dat is Cloud Power.

Start vandaag nog met Windows Azure.

Probeer* Windows Azure gratis. Ga naar microsoft.nl/azure

h

� � � � � � � � � �

h

� � � � � � � � � �

Download de gratis app op http://gettag.mobi

� � � � � � � � � �

h

� � � � � � � � � �

h

* V

oo

r h

et u

itp

rob

ere

n z

ijn c

red

itca

rdg

eg

eve

ns n

od

ig. V

oo

r g

eb

ruik

bo

ve

n h

et in

tro

du

ctie

niv

ea

u b

eta

alt u

he

t sta

nd

aa

rdta

rie

f.

GENERAL

Identifying the elements of the business domainFirst of all, it is important to underline which types of classes partici-pate in the model, simply referred to as the domain model. Alignedwith the paradigm of domain driven design, I recommend to modelthe following types of classes:• Domain objects• Factories• Repositories• Services.

Domain objectsA domain object captures a concept from the real world of the application. Think ofContact, Contract, Company or Address. Domainobject are considered to have identity. Next, domain objects have properties, and these properties have types. Also, domain object deliver services (often implemented as methods).

A number of domain objects in a class diagram

A concept in the business domain should be considered as such if ithas either state (modeled in properties) or delivers services (modeledas operations). Or of course both.

FactoriesFactory classes are used to create new instances of domain objects.Although this can often be achieved by just directly creating a domainobject from scratch, in most domains creating new object is morecomplex, especially with the core concepts in the business domain.For instance, when we created a new Contact, it need to have a leastoneAddress which also needs to be created, and it should be alignedwith the currentCompany. When creating such a construct (often referred to as a aggregate in domain driven design) a factory class isused (and modeled) to holds this creation functionality.A factory class can cover multiple creation scenarios. Name your factory classes after the domain object it creates. Think of classes

such as ContactFactory andCompanyFactory. Model each of thesescenarios as a method on the factory class.

RepositoriesAdditionally to the factory classes, a business domain can have repositories. A repository is responsible for answering enquiries aboutexisting instances of domain objects. For instance, you might want tograb all instances of Contact who live in Amsterdam. Name such repositories after the corresponding domain object. Think of Contact-Repository orAddressRepository. Model such enquiries as methodson the repository associated with the domain object. Please note thatmany projects choose to combine the factory and repository classes.

ServicesSome services in the business domain do not directly correspond toa domain object, but rather apply to several different domain objects.In this case, such as service can be modeled as a separate class, usually with the name of the actual task as its class name. Think of aservice such as ImportFromExcel that imports a project, its work itemsand their estimates into a dashboard. As an alternative, projects maychoose not to model separate factories, repositories and services, butrather add all their functionality as services on the actual domain object. In this case, I would recommend stereotyping these methodsfor example as factory method, repository method or service, so theirpurpose is immediately clear. Please note that even though now thesemethods are modeled on the domain object, they will likely not be implemented there, but on the actual factories and repositories. Thisalternative is merely a technique to avoid cluttering the domain modelwith unnecessary classes. Domain models are full enough without adding factories and repositories.

Identifying propertiesNow let’s delve down to the domain objects, clearly the most important type of class in the domain model. Next to delivering services, domain objects have properties, such as Name, Email, City,Country, Level.

A domain object Contact with a number of public properties

Modeling your domaindriven design in UML

Sander Hoogendoorn

magazine voor software development 25

In any given system under development, the business domain of that system is key. It holds all concepts important to the domain, and captures the business logic from the domain. An important question to answer is what to model about the objects in that domain and how to model this in UML classdiagrams.

GENERAL

MAGAZINE

26

You will need to identify all meaningful properties on your domain objects. Basically you will need to identify all properties that a domainobject exposes to the outside world, either other classes in the domain, user interface elements that bind to it, use cases or persistency layers. These are the public properties of the domain object.

Do not model fields that are internal to a domain object as these arenot relevant to the business domain but in most cases are only relevant to the developers. Thinks for instance of the Id of a domainobject, that is required to store it in a database or to a web service.A special reminder goes out to properties that are not persisted but arecalculated or assembled by the other properties and fields of the domain object. These are called derived properties, and should bemarked as such in the domain model.

Modeling property typesAnd each of these properties has a type. These types actually holdquite a lot of information on the business domain - maybe even morethan you’d expect.

I consider the following types of property types:• Basic types such as string, DateTime, float.• Values types or objects such as ISBN, Email or BSN.• Enumerations• Variable lists.• Associations.

Basic typesMany properties will appear to have a basic type, such as number,string, date,timestamp, float. However, note that for a whole lot of properties, you actually quite a lot more than that it’s just a string. Therefore, for each property check properly if you know more about itthan that it just has a basic type.

Value types or objectA value type or object is an object that is recognizable by its value,but where we are not interested in it’s identity. For instance, two instances of my email address will appear to be the same, while twoinstances of Company that can have exactly the same values for allproperties can still be two different companies.

EnumerationsSometimes, a property can only have a limited set of values. In thiscase you might consider modeling an enumeration (which is a stan-dard stereotype in UML). This enumeration holds the possible values,so next you can model the property of the type of the enumeration.

Enumerations ContactType, PrivacyLevel and Gender

For instance, a domain object Contact might have a Type propertythat be Individual,Group or Family. Now model an enumeration ContactType that holds these values, and model the property Type oftype ContactType.But, there’s a restriction to using enumerations. Only use these if youare certain that the list of possible values is static, that is does notchange over the course of the life of you application. If you need to add

to or change the list of values, this results in re-testing your whole application as the values are often used to perform conditional operations. So if you think the list of values is going to change don’tuse an enumeration. Model a variable list instead.

Variable listsIf a property can only have a value from limited set of values, but thatlist is subject of change during the life of your application, enumerationare not the best solution. The list of values itself should be maintained– either by some software, possibly external to your application, or directly in the database. Think of lists of countries, states or academictitles.Therefore you will need to take extra care of these properties. Nowthere’s a number of options here. If the list only uses standard properties (think of Name and Description) and is just used for reference, you might want to group all these different list into one single domain object (and hence table). In this case, an additional properties is required for this domain object, for instance called Type,that describes the type of element, such asCountry, State, or AcademicTitle. In this option you will only need a single maintenanceuse case to maintain all values in all lists. The value or now availablefor reference, selection or printing on envelopes. We usually refer tothis pattern as Smart Reference.For modeling a property of the type of such a variable list there are anumber of options. Either refer to the type of list in the name of the property (call it Country, State orAcademicTitle) and model SmartReference as the type of the property. This works out fine as long asyou don’t have to properties of a domain object referring to the samevariable list.A more agreeable option is to give the property the name you want itto have, and model the type of the variable list as the type of the property. To make sure the property is recognized as a variable list,add a stereotype (for instance smartreference) tot the property.

AssociationsAnd then there’s the option that would want to refer another domainobject. In this case you normally model an association rather thanmodel a property. An association models a structural relationship between two (or more, but don’t go that road) objects in your businessdomain. So if a contact has zero, one or multiple relationship, you canmodel this as a one-to-many association between the domain objectContact and Relationship in your domain model.

Two (named) associations between Contact and Relationship

In code all associations (as in UML) are represented by properties thatexist on both classes. So in the example Contact will have a propertythat represents a list of relationships. And vice versa, each Relations-hip will have a property of type Contact. Unless you add additionalnames to the ends of the association in the domain model, the namesfor these properties are undefined. However it’s a good habit to namethem after the domain object they come from. So the properties willsimply be calledContact.Relationships and Relationship.Contact -mind the plural.However, if there’s two different associations between the same domain objects, applying this default naming patterns isn’t enough. It would result in multiple properties with the same name. In that casealways specify meaningful names explicitly to the ends of the association. For instance if another association (one-to-one) betweenContact andRelationship exists that identifies who’s the from and

GENERAL

magazine voor software development 27

who’s to to in the relationship, this could result in properties Contact.Froms (a list of type Relationship) and something likeContact.Tos (also a list of type Relatioship).Another reason for specifying meaningful names to association endsis that these simply occur in the vocabulary of the business domain.

Adding validationsThe next step is to add validations to you domain model, and yourdomain objects in particular. I’ll look at the following types of validati-ons:• Are properties mandatory or not?• Is the property valid if the type is a value object?• Is the property correctly formatted?• Does the domain object adhere to the defined business rules?

Mandatory propertiesMost properties on domain objects will be mandatory (although debatable). Therefore by default the multiplicity for a property is set to[1..1], which means that there is to be exactly one occurrence for thisproperties on each object. If a property is not mandatory for the domain object to be valid the multiplicity of such a property is set to[0..1] – which implies that zero or one instances of this property arepresent.

Mandatory and non-mandatory properties

In the example above, BirthName is not mandatory, but AlternativeEmail2 is.

Value objectsThe use of value types of objects in your domain objects explicitly addsvalidation to your objects. It means that the validations rules for thisparticular value object will apply to such a property automatically. If aproperty is defined using type Email, all values (when checked) needto follow the rules defined on the value object Email that define whensomething is in fact a valid Email. Of course, these validations can bestbe modeled on the value object itself.

Properties that have a value object as their type (Email)

In code, this could results in the following property for class Contact(using the ADF.NET framework).

1: public Email AlternativeEmail2

2: {

3: get { return state.GetValue<Email>(ContactDescri-

ber.AlternativeEmail2); }

4: set { state.SetValue(ContactDescriber.AlternativeE-

mail2, value); }

5: }

FormattingSome properties follow a certain format. Think of properties repre-senting money or dates. If the type of the property is a value object,the format should be specified there (often as a regular expression). If not, model the format with the property. Please note that formattingis often culture specific.

Formats can include aspects such as length attributes, for instance astring may not be longer than 64 characters, or must be within a cer-tain range, for instance when a value must be larger than 0 but smal-ler than 128.

Business rulesAdditionally domain objects can validate business rules. For instanceon a domain objectRelationship, a business rule may validate that bothcontacts in the relationship match some relationship type. This can bedefined in an operation (or a method in code) calledToContactMust-MatchRelationshipType. Although this seems like an abundant longname, in fact I recommend to name business rules exactly to whatthey’re actually doing. Moreover, I recommend to implement the business rules in code using exactly the same name, thus creatingtraceability.

Modeling business rules in your domain object using the businessrule stereotype

I also recommend to add the stereotype business rule to these ope-rations to distinguish them from other methods your classes have. Incode the business ruleToContactMustMatchRelationshipType couldlook something like this. Here the attribute BusinessRule is attachedto the method for the same reason, and to allow for automatic validation.

1: [BusinessRule]

2: public ValidationResult ToContactMustMatchRelations-

hipType()

3: {

4: return !To.IsEmpty && RelationshipType.To !=

To.ContactType

5: ? ValidationResult.CreateError(this.Prop(r =>

r.To),

"Contact type '{1}' for {0} does not

match required contact type '{2}'.",

To, To.ContactType, RelationshipType.To)

6: : ValidationResult.Success;

7: }

An interesting type of business rule is that where the domain object athand is validated against other domain object (mostly of the sametype). For instance, when adding a newOrderType object, even thoughit is by definition unique (as domain object have identity by nature, usually implemented using an Id property), may not have the samename as any of the other already existing order types. Or a new contract

When to validate?An intriguing question that comes to mind when discussing validationis when to validate the validations? In a traditional Windows user interface one might say that the moment the user leaves a field andmoves to the next the validation for the represented domain object

GENERAL

MAGAZINE

28

property could or should be fired. In a web application typically theuser types in all the fields and then presses submit.Validating the objects at hand should fire all validations, value objects,mandatory properties, formatting, business rules that are valid for theevent (such as save, remove). In the code example from use case Manage Address an Address object is validated and than saved. •

1: public void SaveAddress()

2: {

3:

4: if (this.Execute(

5: () => Address.Validate(),

6: () => Address.Save(),

7: () => SaveContact()))

8: {

9: OK();

10: }

11: }

Sander Hoogendoorn

Sander Hoogendoorn houdt zich in

zijn rol als Principal Technology

Officer bij Capgemini zich vooral

bezig met de innovatie van software

development. Sander is erkend

global thought leader op het vlak

van agile development bij Capgemini. Daarbij is hij onder meer

verantwoordelijk voor Capgemini’s agile ontwikkelplatform, dat

het Accelerated Delivery Platform (ADP) wordt genoemd.

Sander’s expertise loopt van (agile and non-agile) software

ontwikkelmethodieken, schatten, software architectuur, design

patterns, modelering, UML, model driven software development,

.Net, Java en tools. Zijn laatste boek Dit is Agile geeft een perfecte

inleiding op Agile werken.

Hoeveel tijd ben jij kwijt aan het zoeken, onderhouden, runnen en organiseren van je unit tests?Teveel? Of helemaal niets omdat je er gewoon niet aan begint?

Wouter de Kort

Unit Testen kan veel makkelijkerUnit Test verbeteringen in Visual Studio 2012

DESKTOP

Unit testen is gelukkig iets wat steeds meer ingeburgerd begint teraken. Dit komt onder andere omdat de ondersteuning voor het werken van unit tests in onze ontwikkeltools steeds beter wordt. VisualStudio 2012 heeft hierin grote sprongen gemaakt. Ondertussen heeftMicrosoft ook al weer een update uitgebracht voor Visual Studio enkomt de tweede update er aan. Allebei hebben ze een aantal handigeverbeteringen voor het werken met unit tests. In dit artikel wil ik korteen paar hoogtepunten bekijken die ik zelf erg handig vind.

De nieuwe Test ExplorerDe grootste verbetering op unit test gebied in VS 2012 is de manierwaarop je je unit tests kunt vinden, runnen en de resultaten kunt bekijken. Dit is nu allemaal netjes weergegeven in één overzichtelijkscherm: de Test Explorer.In Afbeelding 1 zie je de nieuwe Test Explorer. Deze laat duidelijk zien hoeveel unit tests je hebt en wat destatus is. Zoals je kunt zien zijn er in dit project drie unit tests waarvaner 1 gelukt is, 1 een fout heeft en 1 nog niet gedraaid heeft. Een handig zoekveldje zorgt ervoor dat je snel door een grote hoeveelheidaan tests kunt zoeken.

De Test Explorer ontdekt automatisch welke unit tests er in je projectaanwezig zijn. De grootste verbetering is dat dit proces gemakkelijk uitte breiden is. Een unit test framework (zoals bijvoorbeeld NUnit, xUnitof Chutzpah) kan eenvoudig een adapter interface implementeren om

Afbeelding 1

aan te sluiten bij de Test Explorer. Op deze manier kan de Test Explorer alle unit tests in je project weergeven die er zijn, ook als zemet meerdere test frameworks geschreven zijn. Je kunt nu dus je JavaScript unit tests combineren met je C# tests en deze allemaal inéén keer draaien.

DESKOP

Runnen en groeperen van testsOok wat het runnen van Unit Tests betreft is er veel verbeterd. Eén optie die vooral de Test Driven Development ontwikkelaars zalaanspreken is de optie om alle unit tests na iedere build te draaien. Unittests die failen worden hierbij als eerste gedraaid. Dit brengt je dussnel in de modus waarbij je na een korte wijziging even je code builden automatisch de unit tests draait. Dit kun je natuurlijk eenvoudig aanen uitzetten terwijl je bezig bent.

Afbeelding 2

Microsoft heeft ook beloofd om regelmatig een grote update voor Visual Studio vrij te geven. Update 1 is inmiddels geweest en heeft demogelijkheid om je tests te groeperen toegevoegd. Dit kan onder andere op Duration en Outcome maar ook op Traits. Traits bestaan uiteen aantal attributes die je kunt gebruiken voor je tests zoals Test Category, Test Property, Priority en Owner. Deze attributes kun je gebruiken om je tests te groeperen en op die manier ook eenvoudigalleen bepaalde unit tests te draaien. Een handige manier om snel jemogelijkheden voor Traits uit te breiden is door je eigen maatwerk attributes af te leiden van de bestaande. Deze kun je daarna gewoongebruiken en ze worden netjes herkend door de Test Explorer.

Ondertussen is ook de CTP van Update 2 nu beschikbaar. Een nieuweoptie hierin is de mogelijkheid om Playlists aan te maken. Je kunt eenvoudig unit tests toevoegen aan een playlist en op die manier snelselecteren welke unit tests je wilt draaien. Dit kun je bijvoorbeeld gebruiken om je unit tests van je integration tests te scheiden of welkeandere manier je ook maar handig vindt. Zelf vind ik dit prettiger werken dan Traits maar beide hebben in de praktijk hun nut. Update2 voegt daarnaast ook nog de mogelijkheid toe om je unit tests opClass te groeperen.

Profilen en Code CoverageNaast het runnen van je unit tests bied de Test Explorer je toegang totalle andere dingen die je maar met je unit test zou willen doen. Zoals afbeelding 2 laat zien kun je eenvoudig één enkele unit test opzoeken, debuggen, profilen of de code coverage berekenen.Vooral het individueel profilen van unit tests is erg handig. Iedere keerkun je exact hetzelfde proces uitvoeren zodat je de resultaten met elkaar kunt vergelijken. Op deze manier kun je zien of je aanpassingenecht zorgen voor betere performance. Code Coverage is handig omte zien hoeveel van je code precies getest wordt door je unit tests. Je moet dit natuurlijk wel op een verstandige manier gebruiken. Eenhoge coverage moet geen doel op zich zijn. Het zegt namelijk nietsover de kwaliteit van je unit tests. Het kan zijn dat deze alleen eenstukje code uitvoeren zonder echt de resultaten te checken.

Maar in combinatie met goede unit tests kan code coverage je wellaten zien welke delen van je code nog wat aandacht nodig hebben.

Wat zal de toekomst brengen?In de laatste twee updates heeft Microsoft veel aandacht besteed aanhet makkelijker groeperen, filteren en runnen van unit tests. Microsoftgeeft aan dat ze veel kijken naar Visual Studio Uservoice (http://visualstudio.uservoice.com) om hun product backlog mee tevullen. Momenteel staat daar met stip op één de vraag naar de terugkeer van ‘Create Unit Tests’ (de mogelijkheid om automatischeen set aan kale unit test s te generen voor een stuk bestaande code). Wat de toekomst ook gaat brengen, met de nieuwe update cyclusvan Microsoft kunnen we er zeker van zijn dat unit tests steeds bruikbaarder zullen worden in Visual Studio 2012. •

magazine voor software development 29

Wouter de Kort

Wouter werkt als freelance Techni-

cal Coach via Seize IT. Hij richt zich

vooral op het geven van maatwerk

seminars, trainingen en coaching

voor alles wat te maken heeft met

de Microsoft Web Stack. Hij begon

met programmeren op zijn 7e, toen

nog in QuickBasic. Hij werd er toen

al snel verliefd op en is daarna

verder gegaan met het programmeren van spelletjes in OpenGL en

C++. Daarna heeft hij nog wat gespeeld met andere talen zoals

Visual Basic en Delphi. Nu werkt hij al vanaf de eerste bèta met C#

en het .NET Framework. Hij zich er op om bedrijven te helpen om

bij te blijven met alle nieuwe ontwikkelingen en deze toe te passen

binnen hun omgeving.

Code Coverage is handig om te zienhoeveel van je code precies getestwordt door je unit tests

Noteer alvast

in uw agenda:

SDN Event

- 7 juni

- 20 september

CLOUD Hassan Fadili

In dit artikel zal ik proberen een van deze toevoegingen te schetsen,namelijk het “Deployment van Web Applicaties naar Windows Azureop basis van Hosted TFS Build en AzureContinuousDeployment BuildProcess Template” Als Visual Studio 2012 gestart wordt, dan is er ookde Team Explorer. In Visual Studio 2012 is deze sterk veranderd, zoalsje hieronder kunt zien:

Fig. 1: New Team Explorer 2012 Layout

Vanuit de Visual Studio 2012 Team Explorer kun je met een link naarde Web omgeving (Web Access) van het desbetreffende Team Project

Continuous Delivery /Deployment met TFSAzure 2012 ReleaseMet de komst van Visual Studio 2012, Team Foundation Server 2012 en de Team FoundationService 2012 (ook wel Hosted TFS 2012 genoemd) wordt er een nieuwe werkwijze geïntroduceerd. Deze nieuwe werkwijze heeft vooral betrekking op onze manier van omgaan,het managen en deployen van ons Builds. Over het algemeen moeten builds gedistribueerdworden naar verschillende onderdelen van een OTAP omgeving. Dit hele proces is deze keer nogverder sterk verbeterd en er zijn nieuwe deployment stappen toegevoegd.

te gaan. In het onderstaande plaatje is deze Web Access link voor de“Hosted TFS Demo” Team Project weergegeven.

Fig. 2: Nieuwe Team Explorer 2012 weergave en link naar Web Access portal

Als op deze link geklikt wordt, dan wordt er een connectie met de desbetreffende Team Foundation Service gezocht. In dit geval is datde https://hassanfad11.visualstudio.com/DefaultCollection/Hosted%20TFS%20Demo instantie van TFS Service. Je moet je aanmeldenzoals hieronder is weergegeven, om toegang tot de Web omgevingvan de Team Project te krijgen.

Fig. 3: Authenticatie/ Autorisatie met behulp van een Microsoft Account naar Hosted TFS Demo Team Project

MAGAZINE

30

CLOUD

Als het inloggen gelukt is en je ook rechten op het project hebt, danwordt de Web Access page getoond. Deze ziet er ongeveer als volgtuit:

Fig. 4: TFS web acces page

Om gebruik te kunnen maken van Windows Azure Deployment incombinatie met de TFS Service Build Management, hebt je uiteraardeen Windows Azure subscription nodig. Met deze Windows Azuresubscription wordt de mogelijkheid geboden om de verschillende services van Windows Azure te gebruiken, zoals websites, cloud services, virtual machines, mobile services, storage, etc. De Azure omgeving ziet er als volgt uit:

Fig. 5: Windows Azure Services

Fig. 6: Set up TFS Publishing for Website under Windows Azure

Met een Windows Azure subscription kun je gebruik maken van allebeschikbare Windows Azure services. Voor dit artikel is een WindowsAzure website gemaakt met de naam (Hassan). Deze heb ik vervolgens geconfigureerd zodat er gebruik wordt gemaakt van deWindows Azure Deployment met TFS Service Build Management. Dit ziet er als figuur 6.

Wanneer je kiest voor Set up TFS publishing, verschijnt er een autorisatie scherm waarin de benodigde gegevens ingevuld moetenworden om een connectie te kunnen leggen met de desbetreffendeTFS Service. Dat ziet er als volgt uit.

Fig. 7: Vereist gegevens voor account autorisatie op Windows Azureomgeving naar TFS Service instantie

Met Authorize Now moet je eerst bevestigen, dat deze connectie gelegd mag worden of niet. Zoals hieronder is weergegeven:

Fig. 8: Autorisatie bevestiging van Azure website voor de opgegeven account

Als je met Accept bevestigd hebt, dan wordt de connectie naar deopgegeven TFS gevalideerd. Als alles goed is gegaan, wordt het volgende scherm getoond. Op dit scherm kan uit de beschikbareTeam Projecten van de opgegeven TFS service gekozen worden.

Wanneer de keuze is gemaakt, wordt de connectie gelegd tussen hetopgegeven Team Project op TFS Server en de Windows Azure instanties zoals in figuur 10 is weergegeven.

magazine voor software development 31

CLOUD

Fig. 9: Het te publiceren Team Project

Fig. 10: TFS Project en Windows Azue link voor Azure deployment

Vanaf dit moment kun je Visual Studio starten en het project met deWindows Azure Website, zoals hierboven is aangegeven, laden envervolgens builden.Met het linken van de het Team Project en het Windows Azure subscription voor Windows Azure Deployment is er automatisch een

Build Definitie (Hassan_CD) aangemaakt. Deze Build Definitie heeft denaam van de Web Site, die is aangemaakt op Windows Azure (in ditgeval Hassan). De Build Definitie is zodanig geconfigureerd dat hetgebruik maakt van de AzureContinuousDeployment.11.xaml BuildTemplate. Op deze Build Template kunnen de gewenste paramaters ingevuldworden zoals (welke Solution gebuild mag worden met dit proces entegen welke configuratie) zoals in figuur 11 is weergegeven.

Omdat de Trigger voor deze gegenereerde Build Definitie op Continu-ous Integration is gezet, zal na iedere Check-In actie vanuit Visual Studio voor dit project een build gestart worden. Onderstaandeschema laat deze optie zien.

Fig. 12: Continuous Integration voor gegenereerde Build Definitie

De resultaten van deze Build actie zullen automatisch te zien zijn opzowel de Build Tab van Team Explorer in Visual Studio, op de Windows Azure portal van de Website op de Deployments Tab, alsook op de Build Tab van Web Access site van het betreffende Team Project. Alle 3 opties zijn hieronder weergegeven:

Fig. 13: Build resultaat op Team Explorer niveau in Visual Studio 2012

Fig. 11: Automatisch gegenereerd Build Definitie op basis van AzureContinuousDepolyment.1.1.xaml template

MAGAZINE

32

CLOUD

Fig. 14: Build resultaat op Windows Azure op Deployments Tab

Fig. 15: Build resultaat op Web Access Dashboard van Team Project

Conclusie:Microsoft streeft continu naar om het leven van de professionals aangenamer te maken, door alle software development aspectengoed te integreren en goed samen te laten werken.Zo zien we dat waar het build proces en de deployment van applicaties naar Windows Azure in het verleden erg lastig waren, hetnu met de komst van Visual Studio 2012 Application Life Cycle Management Tools en Windows Azure Deployment faciliteiten erg eenvoudig is geworden. Op deze manier kan een project team zich focussen op de functiona-liteit en zijn ze niet meer veel tijd kwijt aan het deployment mechanisme van de desbetreffende applicaties/systemen naar hetWindows Azure platform. Ongeacht of het nou staging en/of productie betreft.•

LinksWindows Azure: http://www.windowsazure.com/

Deliver to Azure continuously: http://tfs.visualstudio.com/en-us/learn/build/continuous-delivery-in-vs/

Deploy Windows Azure project from TFS 2010 Build Server:http://deploytoazure.codeplex.com/

Application Lifecycle Management with Visual Studio and TeamFoundation Serverhttp://msdn.microsoft.com/en-us/library/vstudio/fda2bad5.aspx

Announcing a Build Service for Team Foundation Service:http://blogs.msdn.com/b/bharry/archive/2012/03/27/announcing-a-build-service-for-team-foundation-service.aspx

Deploy and Configure Build Agents: http://msdn.microsoft.com/en-us/library/bb399135.aspx

Create a Build Definition: http://msdn.microsoft.com/en-us/library/ms181716.aspx

Visual Studio 2012: http://msdn.microsoft.com/en-us/library/vstudio/dd831853.aspx

Visual Studio ALM + Team Foundation Server Blog:http://blogs.msdn.com/b/visualstudioalm/

FadiliCT Consultancy Web Site for ALM Services and Trainings:http://www.fadilict-consultancy.nl/

Test Release Management Guidance:http://vsartestreleaseguide.codeplex.com/

Rangers Solutions by Version: http://msdn.microsoft.com/en-us/vstudio/ee358787

Compare Visual Studio 2012 editions: http://www.microsoft.com/visualstudio/11/en-us/products/compare

Hassan Fadili

Hassan Fadili is werkzaam als Freel-

ance Lead Architect / Consultant en

VS ALM Consultant (MVP) voor zijn

eigen bedrijf FadiliCT Consultancy

(http://www.fadilict-consultancy.nl).

Hassan is zeer actief in de Commu-

nity en mede bestuurslid van Dot-

Ned (.NET & VS ALM UG NL) en VS

ALM Track Owner. Hassan houdt

zijn blog op: http://hassanfad001.blogspot.com en te bereiken via:

[email protected], [email protected], hassanfad11

@hotmail.com en/of via Twitter op: @HassanFad

Het leven is met de komst van Visual Studio 2012 Application LifeCycle Management Tools en Windows Azure Deployment faciliteiten erg eenvoudig geworden

magazine voor software development 33

DATABASES Robert Jan Boeije

ObjectScopeA way the get around this is prefetching all associated objects andstoring them in the ObjectManager. An easy way of doing this is withObjectScope in combination with the using construct:

The ObjectScope takes care of registering the list of Addresses in theObjectManager and removing them when leaving the using scope.Now we have to make an adjustment to the Get method of the AddressFactory so it first checks the ObjectManager. If there is nothingregistered in the ObjectManager the Addres is fetched from the database, just as usual.

Useful extension methodsIf you don’t want to make your logic more complicated that it alreadyis then you can do the prefetching just in the ContactFactory and stitchthe two lists by setting the addresses on the corresponding contact.

PerformanceMake sure you cache the ID property (or whatever property you’ll besearching on later) of the objects you put in the ObjectManager. Thisproperty will be used heavily and getting the value every time from thestate is, besides being unnecessary, very slow.

For more information about ADF see http://www.accelerateddelivery-platform.com/Frameworks.ashx. Sources can be found: https://github.com/NLADP •

MAGAZINE

34

Using the ObjectManagerThe ObjectManager is like a temporary cache where you can store objects, like DomainObjects. Lazy-loading properties for associations is great for easy of use and readability. Butwhen doing some batch processes, fetching lots of associations can trigger many sub querieswhich will take your performance down the drain.

01 var contacts = ContactFactory.Search(ContactSearchObject);

02

03 var addresses = AddressFactory.Search(ContactSearchObject);

04

05 using (new ObjectScope<Address>(addresses))

06 {

07 foreach (var contact in contacts)

08 {

09 // do something with contact.Addresses

10 }

11 }

1 public static Address Get(ID id)

2 {

3 if (id.IsEmpty) return Empty;

4

5 return

6 ObjectManager.GetItemOrDefault(address =>

address.Id == id,

7 () => new Address(AddressGateway.Get(id)));

8 }

1 using(new ObjectScope<Address>(addresses))

2 {

3 contacts.InitializeProperty(contact => contact.Addres-

ses);

4 }

01 private ID _id;02 public override ID Id03 {04 get { return _id.IsEmpty ? (_id = state.GetValue<ID>(

AddressDescriber.Id)) : _id; }05 }0607 private Contact _contact;08 public Contact Contact09 {10 get11 {12 return _contact ?? (_contact =

ContactFactory.Get(state.GetValue<ID>(

AddressDescriber.Contact)));13 }14 set15 {16 _contact= value;17 _contactId = value.Id;1819 state.SetValue(AddressDescriber.Contact, value.Id);20 }21 }2223 private ID _contactId;24 public ID ContactId25 {26 get { return _contactId.IsEmpty ?

(_contactId= state.GetValue<ID>(AddressDes-criber.Contact)) :

_contactId; }27 }

Robert Jan Boeije

At Capgemini, Robert Jan is active as

a software architect, developer and

agile coach. He is also an active mem-

ber of the Accelerated Delivery Platform

Core Team and one of the committers

of the open source Adf.Net framework.

www.accelerateddeliveryplatform.com

Blog: rboeije.wordpress.com

Twitter @rboeije