SDN Magazine 110Nummer 110 augustus 2011 SDN Magazine verschijnt elk kwartaal en is een uitgave van...

56
Nummer 110 augustus 2011 SDN Magazine verschijnt elk kwartaal en is een uitgave van Software Development Network www.sdn.nl IN DIT NUMMER O.A.: Foto’s maken met Mono voor Android < Skin Widgets in DotNetNuke < iOS en C#, een mooi koppel < Input validatie en output encoding < voor een veiligere ASP.NET webapplicatie SOFTWARE DEVELOPMENT NETWORK MAGAZINE 110 ISSN: 2211-6486

Transcript of SDN Magazine 110Nummer 110 augustus 2011 SDN Magazine verschijnt elk kwartaal en is een uitgave van...

SDN Magazine 110Nummer 110 augustus 2011 SDN Magazine verschijnt elk kwartaal en is een uitgave van Software Development Network
www.sdn.nl
Skin Widgets in DotNetNuke <
Input validatie en output encoding <
voor een veiligere ASP.NET webapplicatie
SOFTWARE DEVELOPMENT NETWORK
Colofon Uitgave:
Roel Hans Bethlehem, Christiaan Heidema,
Bob Swart, Stefan Kamphuis, Peter Donker,
Maarten van Stam, Alexander Meijers, Remi
Caron, Marcel Meijer en natuurlijk alle
auteurs!
Listings:
source files uit deze uitgave.
Contact:
E-mail: [email protected]
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.
Adverteerders Bergler 2
onder de rubriek Magazine.
voorwoord Beste SDN Magazine lezer,
jammer, in mijn vorige voorwoord had ik het over een lange hete zomer. De zomer is
qua weer een beetje tegengevallen ondanks het mooie begin in het voorjaar. Helaas
heeft die warmte niet doorgezet in de zomer. We hopen, dat jullie toch allemaal
genoten hebben van een vakantie al dan niet in verre warme oorden.
Qua nieuwe ontwikkelingen voor ontwikkelaars was het toch een hete zomer. Aan het
einde van de maand juli werd LightSwitch gereleased en werd Windows Phone
Mango vrijgegeven voor de Windows Phone 7 hardware leveranciers. Daarnaast zijn
er nieuwe Visual Studio tools voor Windows Azure vrijgegeven en is er een nieuwe
Windows Azure trainingskit beschikbaar. Kortom er was genoeg om de natte zo-
merdagen door te komen.
Dit magazine bevat weer een geweldige diversiteit aan artikelen. Deze keer zijn ze in-
gedeeld volgens de industriestromingen waar wij als SDN op focussen. Deze
stromingen zijn Web, Desktop, Mobile en Cloud. Ook Delphi en DotNetNuke
artikelen vallen in deze categorieën. Sterker nog deze keer hebben we een heel
aardig artikel over Delphi en Azure. Wie zegt dat Delphi een legacy omgeving is, dit
artikel bewijst het tegendeel. Voor de Software Architecten een uitgebreid artikel over
DYA. Dat wij als SDN niet gebonden zijn aan het Microsoft platform bewijzen de
artikelen over Andriod en iPhone wel. Oké, C# is in beide gevallen wel de program-
meer taal.
Ondertussen zijn we ook al weer bezig met de organisatie van de SDN Conferences
2011. Deze keer organiseren we deze voor de 20-ste keer. Helaas kunnen we nog
niet heel veel kwijt over de precieze invulling, maar het belooft wel een mooi spekta-
kel te worden. Ook deze keer gaan we over de industrie-assen, dus hebben we
aparte tracks voor Desktop, Web, Mobile en Cloud. Daarnaast komen ook DotNet-
Nuke en Delphi met eigen tracks weer volledig tot hun recht. De maandag avond
belooft voor de Delphi track reuze interessant te worden! Voor de andere conferences
zijn we met een echte knaller bezig! Als je hier niet geweest bent, dan heb je wel iets
gemist! Kortom, hou de website www.sdc.nl in de gaten en schrijf je in! Kosten tech-
nisch is de SDN Conferences 2011 heel aantrekkelijk en zoals altijd is de content
perfect! Laat de ingesloten flyer vooral zien aan vrienden en collega’s.
Rest mij jullie nog heel veel leesplezier! We hebben onze uiterste best gedaan er weer
een erg mooi magazine van te maken. Volgens ons is dat gelukt. Mochten jullie
vragen c.q. opmerkingen hebben, laat het dan weten op [email protected] of
[email protected].
Marcel •
04 Inhoudsopgave
04 Agenda
05 Foto’s maken met Mono for Android Willem Meints
10 Azure Applications with Delphi XE Marco Cantù
14 MVVM met Catel Geert van Horrik
17 Ik weet alles beter! (Of toch niet?)
Michiel van Otegem
Hubert Klein Ikkink
Theo Neeskens
30 Querying nested groups in Active Directory
Mark Dirksma
33 iOS en C#, een mooi koppel Roy Cornelissen
40 Input validatie en output encoding voor een veiligere ASP.NET webapplicatie
Alex Thissen
Robert Deckers
49 Skin Widgets in DotNetNuke
Will Strohl & Armand Datema
• Delphi XE2 Seminar (Helmond)
magazine voor software development 5
Foto’s maken met Mono for Android Het ontwikkelen van mobile apps is helemaal in. Via de appstores van Apple en Google kun je de wereld aan apps vinden voor zo ongeveer alles wat je maar wilt hebben. Ik kan mij voorstellen dat je zelf een app wilt ontwikkelen om deze vervolgens in de appstore te publiceren. Je kan dat doen met de standaard ontwikkeltools van Google of Apple, maar als je .NET programmeert in het dagelijks leven dan is er ook een andere manier om apps te ontwikkelen.
In dit artikel laat ik je zien hoe je met Mono for Android een Android app kan ontwikkelen waarmee je een foto kan maken en weergeven op het scherm.
Wat is het Mono for Android framework? Het Mono for Android framework is een implementatie van Mono op het Android platform. Novell heeft ervoor gezorgd dat je als .NET ontwikkelaar met je bestaande .NET kennis een app kan ontwikkelen op het Android platform. Daarbij kun je gebruik maken van alle bekende programmeerinterfaces zoals LINQ, WCF, Threading, Sys- tem.Xml en andere veelgebruikte onderdelen van het .NET framework.
Fig. 1: Architectuur Mono for Android
In figuur 1 is te zien hoe de architectuur van het Mono for Android framework er uit ziet.
Om het Mono framework te laten communiceren met het Android plat- form heeft Novell een aantal specifieke architectuur keuzes gemaakt. Zo is het Mono framework niet boven op de Dalvik runtime gebouwd. De Dalvik runtime is de java virtuele machine waarop alle apps binnen Android worden uitgevoerd. In plaats van Mono bovenop de Dalvik engine te draaien is er een apart systeem ontwikkeld dat rechtstreeks op de Linux kernel van het Android OS draait. Dit maakt het mogelijk om de reguliere Mono JIT compiler te gebruiken samen met de eigen garbage collector.
Apps op Android kunnen worden gestart vanuit de launcher of door op de widget te drukken op het bureaublad van je telefoon. Zowel de launcher als de widgets kunnen alleen worden geimplementeerd door
het schrijven van Java code. Om toch Mono for Android apps te kunnen starten wordt er voor elke .NET class, die aangeroepen moet kunnen worden vanuit Android, een Android Callable Wrapper (ACW) gegenereerd door de Mono for Android compiler. Een ACW kan het beste worden gezien als de stunt-double van een .NET class.
Er is door Novell gekozen om met Mono for Android zo dicht mogelijk de native omgeving te benaderen op het Android platform. Net als reguliere Android apps bestaat daarom een Mono for Android app uit een serie activities waarvan er een is geregistreerd in de eerder genoemde launcher. Een Activity is echter een Java class. Om deze class te kunnen gebruiken is het noodzakelijk om hiervoor een zogenaamde Mono Callable Wrapper (MCW) te gebruiken. Dit is net als de ACW een stunt-double, maar dan voor een Java class. ACW componenten en MCW componenten zijn componenten die intern communiceren via de JNI (Java Native Interface). Java en Mono praten nooit rechtstreeks tegen elkaar, maar altijd via de Mono runtime die op de Linux kernel draait. Deze vertaalt daarbij allerhande zaken op een zodanige manier dat als er wordt verwezen naar een Java object er aan de Mono kant een .NET object bestaat en andersom.
Het Mono for Android framework draait voor een groot deel om vertaalslagen tussen Android en Mono. Novell heeft er voor gezorgd dat ontwikkelaars hier geen grote hinder van ondervinden. De gehele Android API is voorzien van een .NET saus zodat je geen getProperty() en setProperty() methodes meer ziet, al dit soort constructies zijn omgezet in .NET native constructies.
Je eerste app ontwikkelen Voordat je kan beginnen met het ontwikkelen Mono for Android moet je de nodige voorbereidingen treffen. Voor het kunnen compileren voor Android heb je de Android SDK nodig. Deze kan je downloaden vanaf de Android developer website. Nadat je hem hebt gedownload moet je de SDK manager van de Android SDK eenmalig starten om de rest van de SDK te installeren op je computer.
Naast de Android SDK heb je ook de Mono for Android componen- ten nodig. Deze kun je vinden op de website van Mono for Android (http://mono-android.net/).
MOBILE
MAGAZINE
6
Als je na de installatie Visual Studio 2010 opstart en een nieuw project gaat aanmaken zal je een nieuwe categorie project templates aantreffen in het dialoogvenster.
Fig. 2: Mono for Android projecttypes
Mono for Android ondersteunt een drie tal verschillende soorten projecten. Je kan een Mono for Android Application maken, dit is een reguliere Android app. Daarnaast kan je een OpenGL app maken, hiermee kun je een game ontwikkelen voor Android. Tot slot kun je een Mono for Android library ontwikkelen, je kan dit vergelijken met een JAR library voor Android.
Voor het voorbeeld heb ik gebruik gemaakt van de Mono for Android application template. Als je op basis hiervan een project aanmaakt krijg je een structuur waarbij een Activity class is aangemaakt in het project en er een setje mappen is neergezet met wat standaard resource files. In figuur 3 is de structuur weergegeven zoals je hem in Visual Studio 2010 ziet.
Fig. 3: Projectstructuur
Het Android besturingssysteem werkt met zogenaamde activities om delen van apps aan te duiden. Je kan een activity vergelijken met een enkel scherm in een Windows Forms applicatie. Activities zijn echter
wel meer geïsoleerd van elkaar dan dat je gewend zult zijn vanuit Windows Forms. Je kan activities namelijk alleen opstarten doormiddel van intents. Intents zijn berich- ten die je kan versturen richting het Android OS. Deze berichten bevatten een soort adres, namelijk de actie. Daarnaast kun je zogenaamde extra’s meesturen, dit is een dictionary met key-value pairs waarin je extra gegevens kan doorgeven aan de ontvanger van de intent. Intents worden gebroadcast en de eerste app die reageert wint en mag de intent afhandelen. Alles en iedereen mag zich inschrijven voor intents. Je kan bijvoorbeeld je inschrijven op een intent voor het adresboek. Je vervangt dan het normale adresboek van Android met je eigen implementatie.
Het voorbeeld dat ik ga gebruiken is een app waarmee je een foto kan nemen en deze vervolgens kan e-mailen naar iemand
in je adresboek. De eerste stap om richting het kunnen nemen van een foto is het implementeren van de root activity van de app. Er is minimaal één activity in je app die gekoppeld dient te zijn aan de Android launcher om hem te kunnen starten.
[Activity(Label = "PhotoMailer", MainLauncher = true, Icon =
"@drawable/icon")]
{
SetContentView(Resource.Layout.Main);
tArgs e)
Codevoorbeeld 1: FotoMailer activity
In codevoorbeeld 1 is te zien hoe de MainActivity van de app eruit ziet. Boven de class staat een attribuut om aan te geven dat het een acti- vity is en dat hij in de launcher moet worden weergegeven. Dit attribuut wordt door de Mono for Android compiler gebruikt om de juiste infor- matie in het app manifest te zetten. Dit manifest beschrijft hoe je app eruit ziet en welke rechten hij nodig heeft op het Android OS.
In de OnCreate methode kun je de benodigde configuratie doen van je activity, zoals het inladen van een layout file voor de user interface. Dit doe je door de methode SetContentView(…) aan te roepen.
MOBILE
magazine voor software development 7
Aan deze methode geef je het ID van de layout resource mee die je wilt inladen. Deze ID’s worden automatisch voor je gegenereerd op het moment dat je het project een keer compileert. De layout resource ID’s vind je na het compileren terug in Resource.Layout.XX properties.
Je kan in Android op twee manieren met user interface omgaan. Je kan in code de user interface opbouwen of een layout file inladen. Het laatste is een stuk praktischer dan de user interface in code op- bouwen. Je kan namelijk voor allerlei uitgangssituaties layout files pro- duceren. Zo kun je bijvoorbeeld een layout file maken voor portrait en landscape. Je plaatst dan de ene file in Resources\layout-portrait en de andere in Resources\layout-landscape. Zolang je ze dezelfde naam geeft zal Android zelf kunnen uitzoeken welke hij moet weergeven.
De layout van de voorbeeld app bestaat uit twee knoppen en een imageview. De imageview kan je gebruiken om een afbeelding weer te geven op het scherm. De layout is in codevoorbeeld 2 weergegeven.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
Codevoorbeeld 2: Layout file
Zowel de button als de imageview zijn voorzien van een android:id attribuut, met een @+id constructie. Door deze constructie te gebrui- ken maak je duidelijk aan de resource generator dat je graag een nieuw ID wilt hebben. Je kan ook gebruik maken van bestaande ID’s uit de Android omgeving. Dit gebruik je voor constructies waarbij je een bestaande user interface wilt aanpassen specifiek voor jouw app. In het codevoorbeeld zie je op een aantal punten een vermelden met @string staan. In Android kun je gebruik maken van zogenaamde string files waarin je de teksten die je wilt gebruiken in de user inter- face kan bewaren. Op deze manier kun je de user interface vertalen in meerdere talen. Om gebruik te maken van deze teksten geef je ze in de string file een naam en refereer je naar deze naam doormiddel van de @string/naam constructie in je layout files.
Een foto nemen Nu de basis van de applicatie staat, is de volgende stap het toevoe- gen van functionaliteit om een foto te nemen. Het nemen van een foto op Android doe je door een intent op te starten en het resultaat ervan weer op te vangen in je activity. Zoals je eerder hebt kunnen lezen wor- den intents gebruikt om te communiceren met het OS. Je hebt dit in het geval van een foto maken nodig, omdat je niet weet welke app de gebruiker van de telefoon heeft geïnstalleerd voor het maken van foto’s.
Voor het nemen van een foto heb je de intent “android.media.ac-
tion.IMAGE_CAPTURE” nodig. Aan deze intent kun je een output file mee geven, maar dat hoeft niet. Geef je het niet mee dan is het de bedoeling dat de activity die de intent implementeert, zelf een naam verzint.
private const int TakePictureRequestCode = 1001;
private void OnTakePictureClicked(object sender, EventArgs
e)
Intent intent = new Intent(MediaStore.ActionImageCap-
Codevoorbeeld 3: Een foto nemen
In codevoorbeeld 3 is te zien hoe je de camera kan starten. Je ziet de naam van de intent niet meer terug in de code, omdat Novell hiervoor een constante heeft gegenereerd in de Mono for Android library. Je vind de intent voor het nemen van een foto en andere media gerelateerde intents terug op de MediaStore class.
Om het resultaat van de camera op te kunnen vangen start je de intent op met de methode StartActivityForResult. Bij het starten kun je een requestcode opgeven. In het volgende codevoorbeeld zal je zien hoe je hier handig gebruik van kunt maken. De app kan met de code in codevoorbeeld 3 prima foto´s maken alleen krijg je ze nooit meer terug. Om de foto namelijk terug te halen moet je de methode OnActivityResult overriden in je activity.
protected override void OnActivityResult(
Codevoorbeeld 4: Resultaat van de camera opvangen
In de OnActivityResult methode krijg je een intent terug met daaraan de data van de activiteit. Daarnaast krijg je een requestcode en een resultaatcode terug. De requestcode die je hier terugkrijgt komt overeen met de requestcode die je bij het starten van de intent hebt opgegeven. Als je in deze methode terechtkomt is het belangrijk om te controleren of de activiteit gelukt is. Dit doe je door te controleren de resultCode overeenkomt met de waarde Result.OK. Daarnaast moet je controleren voor welke intent je data terug hebt gekregen. Als je namelijk meerdere intents tegelijk opstart in je app kan het zijn dat het resultaat van de ene intent eerder terug is dan van de andere.
MOBILE
MAGAZINE
8
Als je een foto hebt genomen met de camera intent krijg je een URI terug van de afbeelding die is genomen door de camera. Deze URI kun je vervolgens koppelen aan een imageview om de foto weer te geven.
Hinken op twee gedachten In de voorbeeld app merk je niet veel van het feit dat Android op Java is gebaseerd. Maar hoewel je .NET programmeert met Mono for Android zul je het Java aspect toch nog overal terug vinden in de apps die je ontwikkelt.
Onderdelen van de app die gebruik maken van de Android voorzie- ningen hebben dikwijls classes nodig die zijn afgeleid van Java.Lang.Object. Je zult merken dat het gehele Mono for Android framework eigenlijk een beetje op twee gedachten hinkt. De ene keer heb je te maken met System.Object en de andere keer heb je te maken met Java.Lang.Object. In de praktijk levert dit niet heel vaak problemen op. Het punt waarop je er wel mee te maken krijgt is bijvoorbeeeld op het moment dat je een web service reference aan je app hebt toegevoegd en je objecten daaruit wilt weergeven op de user interface. Om objecten in een lijst op het scherm te tonen maak je gebruik van een zogenaamde ListAdapter. Een ListAdapter vertaalt elk object in zijn data source naar een view op het scherm. De List Adapter gaat uit van Java.Lang.Object gebaseerde objecten in zijn data source. Deze heb je echter niet als je objecten ophaalt van een webservice die je via een service reference hebt gekoppeld aan je app.
Een oplossing voor dit scenario en vergelijkbare scenario’s is gelukkig eenvoudig te implementeren. In codevoorbeeld 5 is een wrapper geschreven die het mogelijk maakt om objecten die niet zijn afgeleid van Java.Lang.Object toch als zodanig te behandelen.
public class JavaObjectWrapper<T> : Java.Lang.Object
{
JavaObjectWrapper<T> input)
Codevoorbeeld 5: Java object wrapper
Wanneer je zelf een ListAdapter gaat implementeren kun je handig gebruik maken van de wrapper uit codevoorbeeld 5 op het moment dat je een bepaald item uit de gekoppelde lijst moet teruggeven aan het Android OS. Een voorbeeld hiervan zie je in code voorbeeld 6.
public class MyListAdapter<T>: BaseAdapter
{
{
}
// ...
}
Codevoorbeeld 6: Java object wrapper in combinatie met een list adapter
De toegevoegde waarde van Mono for Android De standaard omgeving voor Android is eclipse met de Android SDK. Het Java platform is op zichzelf een prima keuze om Android mee te ontwikkelen, dus waarom zou je wat anders willen? De reden om wat anders te willen doen zit hem niet zozeer in de extra mogelijkheden die Mono for Android biedt. Dit zijn er namelijk maar een beperkt aantal. De echte kracht van Mono for Android zit hem in de mogelijkheid om de C# code, die je hebt geschreven voor je Android app, te kunnen hergebruiken in bijvoorbeeld een Windows Phone 7 app of een MonoTouch app. Om de hoeveelheid code die je kan hergebruiken zo groot mogelijk te maken is het wel zaak om de logica van je app zo in te delen dat je de business logica gescheiden houdt van de logica om de user interface aan te sturen. Op deze manier heb je een groot geheel dat je kan hergebruiken. Het user interface gedeelte kun je vervolgens helemaal toespitsen op Android en er het maximale uit halen qua mogelijkheden die Android biedt. Als je alleen .NET programmeert is Mono for Android ook een prima keuze. Je hoeft namelijk op dat moment alleen de Android specifieke zaken te leren. Je hoeft geen nieuwe programmeertaal te leren en je hoeft ook niet te leren omgaan met de standaard Java classes. Je kan in plaats daarvan gebruik blijven maken van de bestaande kennis die je in de loop van de tijd hebt opgedaan op het .NET platform.
Conclusie Zoals je hebt kunnen zien voelt het ontwikkelen met C# op Android heel natuurlijk aan als je .NET gewend bent. Er zijn en blijven altijd kleine details, die net even anders werken dan je gewend bent, maar over het algemeen is het een solide combinatie. Het wordt zelfs nog krachtiger als je slim nadenkt over de opzet van je app en delen ervan apart zet, zodat je deze code ook kan hergebruiken voor Windows Phone 7 en MonoTouch. De smartphone markt is dusdanig gefrag- menteerd dat als je apps wilt ontwikkelen, voor de diverse populaire platforms, je enorme investeringen moet doen in kennis en tools. Door te investeren in het cross-platform ontwikkelen van apps door middel van C# zul je merken dat je beter in staat bent om apps te produce- ren voor zowel Android, iPhone als Windows Phone 7. Daarnaast zal je merken dat je apps vooral goedkoper kunt produceren.
Links • http://www.mono-android.net/ - Website van Mono for Android • http://developer.android.com/ - Android developer website •
Willem Meints
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, Silverlight en natuurlijk
with
30009
3000emplo
eesyemplo
op-quality softwers tCSC deliv echnology serviction tormainf
t ideas, prs the beso harnesus t e do amazing things. Find out morors. Wsect
e the we aro its clients. We tarop-quality softw e acrxperienc. Our eyompanes cechnology servic
om both the public and prives and solutions fractict ideas, pr om.ct csc.e ae do amazing things. Find out mor
s leading independent orld’e the w tries enables s all indusose acr
e taom both the public and priv
Marco Cantù
Delphi XE Components for Azure Delphi XE includes some components for Azure, but also and moreover a number of lower level classes, which is where the real power is. These classes provide ready-to-use methods for performing the various operations and deal with the complicated security requi- rements of the Azure platform.
The core non-visual component is the one used to configure the connection to the service, called TAzureConnectionString. Although this component has a few quirks in its user interface (it messes up the Object Inspector in the IDE1) it is a handy starting point in which to enter the user name and password of your account. Other visual components offer direct navigation and management of the respective data structures: • TAzureTableManagement is for NoSQL tables2 • TAzureBlobManagement is for binary data (that is, files, images, documents...)
• TAzureQueueManagement is for managing queuing services
These management components are very nice to learn about these services and examine their status, but aren't generally a good end user tool, safe for the real power users. In practical terms, you'll ge- nerally use the low-level classes behind these components rather than the visual “management” TreeView controls. The three core classes, defined in the DSAzure unit, are: • The TAzureTableService class • The TAzureBlobService class • The TAzureQueueService class
Building an introductory Demo, Azure101 In the Azure101 project I introduce both the visual components and the low level classes, focusing on the Table and Blob services. The programs loads the account settings from an INI file. There are two Azure visual controls hooked to this configuration component, as you can see in Listing 1:
object AzureTableManagement1: TAzureTableManagement
ConnectionInfo = AzureConnectionString1
In Delphi XE there is native and specific support for three of the Microsoft's Azure cloud services: Queue, Tables, and Blobs. This article provides a short introduction to these components and the underlying classes, and shows a practical demo of how to use the Azure service compo- nents to publish some database data on a hosted database, and also consume that data. This article is based on the last section of my new Delphi XE Handbook, and the source code is also available from the book Subversion repository at code.marcocantu.com.
Azure Applications with Delphi XE
Active = False
end
Listing 1: The simple properties of the Azure Management components of the demo
As with a database component, you won't generally activate them at design time. Given they might take some time for the setup, you won't probably even turn them on in the OnCreate event handler. In this demo I do it when a button is pressed, turning the Active property of both management components to True. At this point you can use the two controls for browsing the current Tables and Blob containers of your account. You can double click on each of them to open a dialog box with more details. In Figure 1 you can see the information displayed by the TreeViews.
Fig. 1: The Azure101 demo lets you browse your Azure Tables and Blobs
As you can see in the figure, the information about tables is limited, and you'll have to double click on a table to open a dialog and see more. For the Blobs, instead, you can drill into the list of elements in each container and also see the list of the properties, the meta data, and the access control list right into the main TreeView. For the Blobs you can
DELPHI / CLOUD
DELPHI / CLOUD
also use this view to load new files and set their permissions. The button on the side will copy to the clipboard the main URL for your azure data, which in my case is: http://marcocantu.blob.core.windows.net You can combine this URL, the container name, and the object name to figure out its public URL, like (if you look again at the image above): http://marcocantu.blob.core.windows.net/mydata/euro.jpg This can be properly seen in a browser only because I set its Content- Type property to a format browsers should recognize (see the details in the image below). Using a URL like the one above anyone can see the image I uploaded with a Delphi program. In Figure 2 you can see the set of properties for the object:
Fig. 2: The properties of an Azure Blob object in the AzureBlob Management component
In terms of the tables, you need to open the details of one to see its structure, as displayed in Figure 3. Differently from what you might expect, the table data is not displayed in a grid. In fact, this is not a relational database table, but rather a NoSQL table structure, in which each row can have different fields or, to be more precise, named attributes.
Fig. 3: The detailed view of an Azure Table in a dialog displayed by the AzureTableManagement component
Now what is more interesting, of course, is to interact with this table in your code. For example, you can add a new row to a table using the InsertEntity method of the TAzureTableService class. The row infor- mation is passed in JSON format, so you can use Delphi's TJSON- Object class (from the DBXJSON unit) to define the proper data structure. This must have the RowKey and PartitionKey attributes, defined in Delphi with two constants called XML_ROWKEY and XML_PARTITION. The other element is that some rows can have extra fields, which doesn't mean that other rows have those fields empty, but that they won't have them. In fact there is no schema or definition of a table: the table structure is defined by the contents of the records you add to it. In listing 2 there is the code used to add a new row to the table.
procedure TAzure101Form.btnAddRowClick(Sender: TObject);
Log (TableService.InsertEntity('marco1', RowObj));
finally
TableService.Free;
end;
end;
Listing 2: The code used to add new rows to an Azure Table
The other operation done by the program is to query the table for the list of records. This is accomplished by calling the QueryEntities method of a TableService object. The result of this call, however, uses an XML format (basically an ATOM format) that the program logs without parsing it. The interesting element of this approach is that once we have created this data structure (or table), it can be used by anyone with the proper permissions and an Internet connection. There is a cost associated, of course, but quite minimal compared to alternative hosting solutions.
The Azure Publish and Consume Demo The Azure101 demo can get you started using Delphi's Azure support, but it certainly falls short in terms of demonstrating its usefulness. The “management” views are quite nice, but that's hardly the interface you'll want to present to an average end user. That's why I decided to add a second demo, made of two programs: • The first is a publishing application that pulls data from a database and makes it available in an online Azure Table, while the content of graphical fields is published in an Azure Blob.
• The second is a browsing application that pulls the data from the Azure cloud storage and shows it to the end user. Notice that this way the end user doesn't require a connection to the database and can benefit from the high bandwidth offered by Azure.
Publishing the Data to Azure To stick to a classic Delphi theme, the database in question is the Biolife table from the FishFact database. In this case I'm using the ClientDataSet version for simplicity. Let's look at the CloudPublish application first. The main form of this program has two fields referring to the services we are going to use. These are initialized in the OnCreate event handler after loading the account settings from the INI file, like in the previous example. Before publishing the data, you have to create the corresponding containers. To publish the data of a single record, we have to create a JSON data structure, include a row key (in this case the record id) and a partition key (in this case a time stamp), and also post a stream with the image
magazine voor software development 11
DELPHI / CLOUD
Fig. 4: The simple user interface of the CloudPublish example
The first specific operation of the browsing demo is a call to Query- Entities to get a list of the records as XML. This return string is processed using an XML-mapper generated interface. However, to parse the actual content of each node we cannot use the interface, as the presence of a nested XML name space causes the interface to fail whilst reading the information (as requests return empty strings in case of a name space mismatch). The code that parses the XML will add to a list the row and partition keys, which are used later to retrieve the details as a user double clicks on a list item, with the code in Listing 4, and display the information like shown in Figure 5.
procedure TFormCloudBrowse.ListBox1DblClick(Sender: TObject);
Image1.Picture.Graphic.LoadFromStream(memStream);
finally
MemStream.Free;
end;
end;
Listing 4: The code used to retrieve the data and image of a specific record
Again, notice that this browsing application doesn't require a connection to the original database or to a custom web server, but relies only on the tables and images provided by Azure cloud storage, which has almost infinite bandwidth.
using as name the same record id, as you can see in Listing 4 (which incldues also the method used transform the original bitmap image in a JPEG, using a temporary memory stream).
procedure TFormCloudPublish.btnPostOneClick(Sender: TObject);
finally
jpgImg.Free;
aStream.Free;
end;
end;
Listing 3: The code used to publish the database data to Azure
Another button let's you scan the database table and post each record. I haven't told much about the user interface of this program because it is very bare bones, as you can see in Figure 4.
Now let's look at the browsing application, called CloudBrowse. When this form is created, it does an initialization similar to the other Azure programs. For this demo, I'm using a single account, but you can set up Azure to have a separate user with read-only rights.
MAGAZINE
12
magazine voor software development 13
Fig. 5: The user interface of the CloudBrowse example, showing both record data and images
Conclusion It is hard to tell how much cloud computing will be a temporary fad and how much of our computing power will reside in web farms owned by a few companies in a few years time, but what is relevant to notice here is that Delphi can be used in this scenario and that there is no
“single preferred vendor” (like in other architectures) but rather the ability to use services of multiple companies. The net result is that in many cases you can extend your native Windows application with a new reach to the Internet, without having to rewrite them as Web applications. •
Marco Cantù
best-selling Delphi books, including
recent Delphi Handbook series (the
last being a Delphi XE Handbook).
He's also an active user and deve-
loper in the Web 2.0 world and
social web, like Twitter.
cantu.com, blog.marcocantu.com, and twitter.com/marcocantu
De toekomst van MonoTouch en Mono for Android
Miguel de Icaza en zijn team zijn di- rect na hun ontslag gestart met een nieuw bedrijf met de naam Xamarin. Xamarin herbouwt op dit moment MonoTouch en Mono for Android. Het ziet ernaar uit dat ze het intellectueel eigendom van Novell niet meekrijgen, maar omdat bijna het volledige team bij Xamarin in dienst is gegaan, is alle kennis aanwezig die nodig is om de producten nieuw leven in te blazen. Xamarin mikt op een release aan het eind van de zomer en belooft daarbij dat alle Mo- noTouch code “source code compa- tible” zal zijn met hun nieuwe tool.We krijgen vaak vragen over de risico’s rondom de investering in Mono- Touch. Wij zijn ervan overtuigd dat
Xamarin een uitstekende job zal doen bij het herbouwen van deze produc- ten. Tot die tijd loont het zeker de moeite om alvast met de gratis trial versie aan de slag te gaan. En weg- gegooide kennis is het nooit, want je benut enerzijds herbruikbare C#/.NET kennis en anderszijds investeer je in kennis van Cocoa Touch. Mocht het zover komen dat je in Objective-C aan de slag moet, dan zijn de concepten en het framework precies hetzelfde. De kracht van .NET en C# op iOS is echter zo groot dat dit zeer zeker een success gaat worden. Houd vooral de website van Xamarin in de gaten voor nieuws rondom hun producten! http://www.xamarin.com
Veryant Releases New Options for COBOL Modernization CHICAGO, April 11, 2011 – Veryant, the COBOL and Java techno- logy innovator, today announced the immediate availability of isCOBOL Evolve 2011 Release 1. To lower software licensing fees and simplify application modernization, isCOBOL Evolve enables developers to continue programming in a familiar COBOL environ- ment, and at the same time, deploy and enhance applications across multiple platforms in an open Java framework without rewriting code.
Organizations upda- ting legacy COBOL applications with mo- dern Web 2.0 user interfaces can build dynamic GUIs directly in the COBOL langu-
age with the graphical isCOBOL Integrated Development Environ- ment (IDE). Developers can quickly add functionality such as customizable docking windows to GUIs and automatically propose values from a preset list or a user’s history to end users completing form entry fields. In addition to COBOL, the isCOBOL IDE now supports Java, XML, and HTML editing capabilities, as well as a Hex editor and version control with CVS and Subversion, providing a streamlined, industry-standard environment for building, deploying, and testing applications across the entire software lifecycle, regardless of language.
Lees het hele artikel op: http://www.mainframecobol.info/2011/04/veryant-releases-new- options-for-cobol-modernization/
Het zal velen niet ontgaan zijn dat MonoTouch en Mono for Android roerige tijden doormaken. Novell, de leveran- cier van deze producten, is begin dit jaar overgenomen door AttachMate. Die waren met name geinteresseerd in alle Novell patenten. Het Mono team, verantwoordelijk voor de bouw en support van MonoTouch en Mono for Android, is onlangs ontslagen. Daarbij zat ook Miguel de Icaza. Inmiddels staat ook het support voor MonoTouch door Novell op een laag pitje.
registreren van properties veel eenvoudiger (en foutloos) maken.
Een ander voordeel van Catel is dat het werkt met services. Een view model kan gebruik maken van externe services die door middel van een IoC container bepaald kunnen worden. Een voorbeeld hoe men een message box toont is te vinden in listing 2.
var messageService = GetService<IMessageService>();
Catel levert standaard veel services, zoals een IUIVisualizerService (tonen van UI dialogs), IProcessService (starten van processen), INavigationService (navigeren tussen view models), en meer.
Waarom Catel Veel ontwikkelaars zullen zich afvragen waarom er gekozen is om (weer) een nieuw MVVM framework te ontwikkelen. Als we strict kijken zijn er maar enkele serieuze MVVM frameworks. De meest bekende zijn MVVM Light en Caliburn (Micro).
MVVM Light implementeert slechts de basis van MVVM en mist veel “convenience” functionaliteit. Zo is het bijvoorbeeld noodzaak om altijd zelf een PropertyChanged aan te roepen na het zetten van de waarde van een property. Caliburn (Micro) is een framework dat een bootstrapper nodig heeft en dat uitgaat van conventies.
De ontwikkelaars vonden dat beide frameworks niet volledig volde- den aan de wensen van de ontwikkelaars, dus besloten ze een com- binatie te maken die de ruime mogelijkheden van Caliburn(Micro) biedt, maar toch de eenvoud van MVVM Light.
MVVM met Catel
Een ander groot probleem in MVVM is nested user controls, ofwel hierarchie in view models. Het probleem is dat geen enkel framework een oplossing biedt voor dit probleem. De enige mogelijkheden die een programmeur heeft zijn ofwel in een view model een lijst van view models maken en deze binden ofwel een top view model dat ook implementatie verzorgd voor onderliggende user controls. Beide opties waren voor de ontwikkelaars van Catel geen optie, vandaar de behoefte om een eigen framework te schrijven en te delen met de rest van de wereld.
Dit artikel gaat niet in op de basis van MVVM, daar is immers genoeg over geschreven. Mocht MVVM een nieuw begrip zijn, dan wordt aangeraden om eerst de basisbegrippen eigen te maken.
Basis van Catel De basis van Catel is bijzonder eenvoudig. In Catel zit, net zoals in ieder ander framework, een belangrijke class genaamd ViewModel- Base. Dit is de base class voor alle view models. Het verschil met andere frameworks is echter dat de ViewModelBase niet alleen de INotifyPropertyChanged implementeert, maar ook IDataErrorInfo en vele andere interfaces.
Door gebruik te maken van een “dependency properties”-a-like property registratie kan veel plumbing uit handen worden genomen die een developer anders zelf voor zijn rekening moet nemen. Voor- beelden hiervan zijn het aanroepen van het PropertyChanged event en het (opnieuw) aanroepen van validatie. Onderstaande code-voor- beeld geeft aan hoe eenvoudig het is om een property te registreren in een view model:
public string Name
set { SetValue(NameProperty, value); }
RegisterProperty("Name", typeof(string));
Listing 1: Registreren van een property in een view model
Zoals te zien in listing 1 is het bijzonder eenvoudig om een property te declareren. Omdat het registreren van properties soms als boiler plate kan worden beschouwd biedt Catel ook code snippets die het
Geert van Horrik
Catel is een relatief nieuwe MVVM toolkit dat probeert MVVM zo eenvoudig mogelijk te maken zonder daarmee functionaliteit in te leveren. Catel is ontwikkeld omdat de makers op zoek waren naar een MVVM framework dat voldeed aan veel eisen die in grotere applicaties van belang zijn. Zo vonden zij het onnodig om steeds handmatig het PropertyChanged event te moeten aanroepen wanneer ze een property waarde zetten.
Catel werkt met eenvoudige property registratie en services voor externe functionaliteit
Catel combineert de mogelijkheden van Caliburn (Micro) met de eenvoud van MVVM Light
MAGAZINE
14
GENERAL
magazine voor software development 15
Het prettige van Catel is dat het in delen gebruikt kan worden. Een uitstekend voorbeeld hiervan is dat het mogelijk is om alleen de view models te gebruiken in een applicatie. Wanneer men echter meer wil bereiken is het aanbevolen om ook te kijken naar de meegeleverde user controls.
Ondersteunde Platformen Op het moment van schrijven is de nieuwste versie van Catel 1.4. Sinds deze versie ondersteund Catel niet alleen WPF en Silverlight, maar ook Windows Phone 7.
Het voordeel van de Windows Phone 7 implementatie van Catel is dat het veel overhead wegneemt van de ontwikkelaar. Zo is er een navi- gatie service waarmee eenvoudig tussen view models genavigeerd kan worden. Ook ondersteund Catel een GPS emulatie service waarmee eenvou- dig GPS locaties geemuleerd kunnen worden. Een laatste voordeel is dat tombstoning ook geintegreerd is in MVVM waardoor het bijzonder eenvoudig is om hiervoor support in een applicatie in te bouwen.
Nested User Controls Problem Één van de problemen waar veel MVVM ontwikkelaars tegen aan lopen is het “nested user controls” probleem. Het probleem is dat er vaak hierarchie is in een UI die niet opgelost kan worden met één view model. Wat men vaak doet is een view model maken die weer een lijst van andere (sub) view models bevat. Echter, de master view model krijgt dan teveel functionaliteit en ook het unit testen van de functio- naliteit wordt erg lastig. Catel biedt hier een oplossing voor met de UserControl<TViewMo- del> die automatisch zorgt dat een view model aangemaakt wordt voor de control. Het bijzondere van deze user control is dat deze in staat is om de DataContext van zichzelf te injecten in de view model. Op deze manier is het dus mogelijk om een PersonControl te maken met bijbehorende PersonViewModel.
Fig. 1: Schematische weergave “nested user controls” probleem
De constructor van de PersonViewModel accepteert dan een IPerson instantie. Zodra de DataContext van de control een instantie van IPerson bevat zal de user control deze automatisch injecten in de Per- sonViewModel en vervolgens de DataContext vervangen door een in- stantie van de zojuist gecreëerde view model. Onder water zorgt Catel dat alles in originele staat blijft, dus als er wijzigingen komen op de DataContext zal er een nieuwe view model gemaakt worden met de nieuwe DataContext. Figure 1 geeft het probleem schematisch weer.
Unit Testing Één van de sterke argumenten om MVVM te gebruiken is de testbaarheid van loosely coupled applicaties. Catel gaat nog een stap verder door van veel services een test variant aan te bieden. Dankzij deze test varianten kan eenvoudig via een IoC container (Unity) de test variant worden gebruikt in unit tests.
De test implementaties van de services zorgen ervoor dat de services zelf niet gemockt hoeven te worden, al kan dat natuurlijk wel als daar behoefte aan is. Een voorbeeld van het gebruik van een test imple- mentatie is te vinden in Listing 3. In het codevoorbeeld wordt gesi- muleerd dat een gebruiker een modal dialog annuleert en de test controleert of de view model dan inderdaad geen nieuw object aan de Items property toevoegt.
// Check if there are no persons
Assert.AreEqual(0, viewModel.Items.Count,
// Return false on next call to ShowDialog of the service
service.ExpectedShowDialogResults.Enqueue(() => false);
// Call “Add” command, but it should be canceled by user
viewModel.Add.Execute(null);
Assert.AreEqual(0, viewModel.Items.Count,
Listing 3: Voorbeeld van een unit test
User Controls Catel biedt buiten het MVVM framework ook nog user controls aan die het gemak van het ontwikkelen van software kunnen vergroten. Zo is er de DataWindow die afleidt van de Window (of in Silverlight van de ChildWindow) die automatisch veel gebruikte buttons gene- reert zoals OK, Cancel, Apply, maar ook eigen buttons kunnen worden toegevoegd. Ook wordt er automatisch een InfoBarMessageControl toegevoegd die de fouten overzichtelijk weergeeft voor de eind gebrui- ker. Op deze manier kan een ontwikkelaar zich echt concentreren op de functionaliteit in plaats van plumbing.
Ook is er voor WPF een PleaseWaitWindow, een equivalent van de BusyIndicator control van Silverlight.
Catel ondersteunt een GPS service waarmee eenvoudig GPS locaties geemuleerd kunnen worden
Met behulp van de UserControl<TViewModel> class is het mogelijk om user controls met een eigen view model te ontwikkelen
GENERAL
MAGAZINE
16
Fig. 2: DataWindow met InfoBarMessageControl
Fig. 3: PleaseWaitWindow voor WPF
Toekomst Momenteel is het team van Catel druk bezig met het realiseren van Catel 2.0. Dit wordt een grote release waarin de volgende nieuwe features ondersteund worden:
• Auditing (maakt bijv. analytics mogelijk) • WP7 Mango support (inclusief emulatie service voor alle beschikbare sensoren)
• MEF support • Service locator zodat andere IoC containers dan Unity gebruikt kunnen worden
• en veel meer!
De doelstelling is om minstens eens per twee maanden een officiële release uit te brengen. Mocht je niet kunnen wachten tot de officiële release, dan is de volledige source code beschikbaar op http://catel.codeplex.com. Ook is daar meer informatie te vinden zoals documentatie, artikelen en demo applicaties. •
Geert van Horrik
cialiseerd in het ontwikkelen van
xaml based software m.b.v. WPF,
Silverlight en Windows Phone 7.
In zijn vrije tijd vind Geert het leuk
om andere ontwikkelaars te helpen
op verschillende forums zoals die
van MSDN. Naast het helpen van
andere werkt Geert ook aan het Catel framework, een open-
source MVVM toolkit voor WPF, Silverlight en Windows Phone 7.
Twitter account: @GeertvanHorrik
Blog: http://blog.catenalogic.com
World Tour Kom ook en zie wat je kunt verwachten van
de meest indrukwekkende release ooit!
RAD XE 2
Spreker: David Intersimone
Er was een tijd dat applicatie ontwikkeling binnen het Microsoft plat- form simpel en overzichtelijk was. ASP voor het web, VB voor client applicaties, COM voor (business) componenten en SQL Server (of Access) als database. Tegenwoordig is hebben we zoveel dat we door de bomen het bos niet meer zien. Geen industrie die zo snel nieuwe dingen oplevert als de software industrie. Dit verklaart ook waarom we ons steeds minder kunnen veroorloven om eigenwijs te zijn. Er is simpelweg zoveel technologie en zoveel ontwikkeling dat je niet meer overal de fijne kneepjes van kan weten. Wat dat betreft moet een soft- ware ontwikkelaar tegenwoordig net zo general purpose zijn als de computers waarvoor ze software schrijven. De enige manier om dat vol te kunnen houden als een handje vol specialisten ervoor zorgt dat we snel en eenvoudig de beste oplossing kiezen. Binnen bedrijven zie je dit terug in referentie applicaties die door de guru’s opgezet zijn. Jammer genoeg zijn zelfs die guru’s niet onfeilbaar.
Developer Guidance Microsoft is al jaren geleden tot de conclusie gekomen dat ze het ontwikkelaars makkelijk moeten maken om software te ontwikkelen volgens beproefde patronen. Dit is waar onder andere Enterprise Library (inmiddels al op versie 5.0) uit voortgekomen is. Ben je Microsoft .NET ontwikkelaar en heb je nog nooit van Enterprise Library gehoord? Shame On You! (Als je snel kijkt op http://entlib. codeplex.com/ zal ik het niet tegen je baas zeggen.) Recent heeft Microsoft binnen de Developer Guidance groep even flink het gas - pedaal ingedrukt en wordt allerlei nieuwe guidance ontwikkeld, zoals het Silverlight Integration Pack voor Enterprise Library 5.0. Dit Inte- gration Pack bevat modules voor onder andere caching, foutafhan- deling en logging, en validatie. Met de logging module kun je bijvoorbeeld eenvoudig logging toevoegen die automatisch logt naar Silverlight Isolated Storage en dat vervolgens door kan zetten naar de server. Een ander voorbeeld is de validatie module waarmee je onder andere cross-tier validatie kunt verzorgen. Dit zijn basisfuncties die ie- dere applicatie eigenlijk altijd moet hebben. Tenzij je hele specifieke requirements hebt ben je een idioot als je basisfuncties als logging zelf gaat implementeren. De mensen die deze Developer Guidance ont- wikkelen en de vele meer die het reviewen, waaronder Microsoft MVPs weten gezamenlijk echt meer dan jij en hebben scenario’s bedacht waar jij nog niet aan gedacht had. Er zijn overigens ook andere goede logging frameworks, zoals Log4Net, en daarvoor geldt hetzelfde: zij weten meer dan jij.
SOA & Composite Services Een van de nieuwe telgen in de familie van Developer Guidance is de Composite Services Guidance (http://compositeservices.codeplex. com/). Deze is nauw verwant aan de BizTalk ESB Toolkit 2.0 (http://msdn.microsoft.com/en-us/biztalk/dd876606) en gebruikt hier ook dingen van. Echter, daar waar de ESB Toolkit helemaal gericht is op BizTalk, is de Composite Services Guidance ook van toepassing op WCF, Workflow Services en Windows Server App Fabric. Dit brengt het implementeren van zaken die voorheen erg prijzig waren binnen het bereik van de gewone stervelingen. De Composite Services Guidance bevat onder andere kant en klare voorbeelden voor het centraliseren van webservices schema’s, metadata en policies, en wat je daar dan mee kunt. Mijn favoriet is echter de implementatie van Repair & Resubmit met behulp van een Workflow Service. Repair & Resumbit is een patroon dat je kunt gebruiken in (complexe) proces- sen die aan elkaar gekoppeld zijn met webservices. Het idee is dat wanneer er een fout optreedt omdat de ontvangende partij de inhoud van het bericht niet slikt, een functioneel beheerder in staat is om de inhoud van een bericht aan te passen en dan opnieuw naar de ont- vangende partij te sturen. Met de ESB Toolkit was dit in BizTalk al goed te doen, maar nu kan het ook met Workflow Services gehost in Wind- ows Server AppFabric. Ondanks dat de ESB Toolkit bedoeld is voor gebruik met BizTalk, gebruikt de Composite Services Guidance onderdelen waarvoor BizTalk niet vereist is. Welke onderdelen gebruikt worden zie je in Afbeelding 1.
Afbeelding 1, Repair & Resubmit met Composite Services Guidance
Het Repair & Resubmit patroon stelt ons in staat om robuuste, fout- tolerante webservices te ontwikkelen, zonder dat we hier heel veel tijd aan hoeven te besteden. En vooral om dat laatste is het Developer Guidance te doen. Het moet een no-brainer zijn om dit soort zaken standaard in te bouwen als het nodig is en daarvoor moet het niet nodig zijn om tot in de puntjes te weten hoe alles werkt. Alles wat je hoeft te weten is dat het goed werkt. Zoals Michael Okuda, een van de technische breinen achter Star Trek: The Next Generation, op de vraag "How does the Heisenberg compensator work?" antwoorde "It works very well, thank you." •
Software ontwikkeling is een vak voor eigenwijze mensen. Ik kan het weten, want ik ben zelf ook vreselijk eigenwijs. Ik heb daar ook een goede reden voor: ik ben vreselijk goed in mijn vak. Al die andere architecten en ontwikkelaars zijn idioten. Toch moet ik erkennen dat ik steeds vaker moet steunen op de kennis en het werk van anderen.
Michiel van Otegem
Ik weet alles beter! (Of toch niet?)
Er is simpelweg zoveel technologie en zoveel ontwikkeling dat je niet meer overal de fijne kneepjes van kan weten
magazine voor software development 17
DESKTOP Hubert Klein Ikkink
CodeNarc heeft op dit moment 241 regels die we kunnen toepassen op onze Groovy code. De regels variëren van simpele syntax zaken tot naamgevingsconventie of specifieke implementatie regels. Naast de bestaande regels is het ook mogelijk om zelf regels nog aan te passen of nieuw aan te maken. Hierdoor is het mogelijk om voor onze eigen projecten de juiste set van regels te maken en toe te passen.
Laten we eens kijken wat CodeNarc kan signaleren in de volgende Groovy code:
package com.vxcompany
import java.text.*
import java.util.logging.*
class SampleClass {
Double sum
}
}
De volgende figuren tonen de resultaten van de analyse die CodeNarc heeft uitgevoerd in de gegenereerde HTML rapportage:
We gaan eens in meer detail kijken naar de resultaten. Een duidelijke regel die overtreden wordt is EmptyCatchBlock. In de code zien we dat het try/catch blok in de methode setSumAsString(String) geen implementatie heeft in het catch gedeelte. Hierdoor wordt een even- tuele fout bij het vertalen van de String waarde naar een Double niet doorgegeven aan de code die deze methode aanroept en zal de exceptie niet naar voren komen bij de uitvoering van de applicatie. We moeten wel iets zinnigs doen met de exceptie of gebruik maken
Code reviews zijn een krachtig middel om de kwaliteit en consistentie van code op een project te verhogen. Deze reviews kunnen worden gedaan door bijvoorbeeld andere ontwikkelaars op een project als peer-review. Maar we kunnen bepaalde zaken ook vinden en signaleren door het gebruik van code analyse tools. We kunnen voor Groovy code gebruik maken van een code analysis tool met de naam CodeNarc. CodeNarc is te vergelijken met Checkstyle, PMD of Find- Bugs dat we kennen voor Java code. CodeNarc maakt het mogelijk om geautomatiseerd regels los te laten op de source code. Afwijkingen op de regels worden gerapporteerd en eventueel wordt een alternatieve implementatie getoond.
CodeNarc Analyseer je dynamische Groovy code
MAGAZINE
18
DESKTOP
van Groovy’s exceptie mechanisme, waarbij excepties automatisch vertaald worden naar run-time excepties. De EqualsAndHashCode regel kijkt of we een equals(Object) methode definiëren en als dat zo is dat we dan ook de hashCode() methode hebben geïmplementeerd. Het is erg verstandig om beide methoden te definiëren in een klasse, zodat een object van deze klasse goed te gebruiken is bij sorteren of als key in Map klassen.
CodeNarc bevat een hoop regels die specifiek kijken naar code om te zien of de code meer kan voldoen aan de Groovy syntax. Deze regels zijn erg handig voor ontwikkelaars met een Java achtergrond en nu Groovy code schrijven. CodeNarc geeft bij de regels meteen aan welke alternatieve Groovy syntax gebruikt kan worden. In ons voorbeeld zien we dat de regels ExplicitCallToEqualsMethod en ExplicitCallToPlus- Method aangeven dat we in plaats van methode aanroepen ook operators kunnen gebruiken. ExplicitHashMapInstantiation geeft aan dat we de simpele syntax [:] kunnen gebruiken voor het aanmaken van een HashMap. En we zien hoe we in Groovy minder code hoeven te schrijven met de regels UnnecessaryDefInMethodDeclaration, UnnecessaryReturnKeyword en UnnecessarySemicolon.
Een groot voordeel van een analyse met een tool als CodeNarc is dat ook kleine typefouten of copy-paste foutjes ook ontdekt worden. Dit zijn vaak zaken die je met een handmatige code review over het hoofd kan zien. Was het bijvoorbeeld opgevallen dat de tostring() methode fout is gespeld? We bedoelen hier toString() en dat is ook wat de regel ObjectOverrideMisspelledMethodName aangeeft. De regel Logger- ForDifferentClass geeft aan dat een Logger object wordt aangemaakt voor de Sample klasse, maar we bedoelen de SampleClass klasse. Deze fout kan bijvoorbeeld komen door het kopiëren van een stuk code uit een andere klasse en dan vergeten we de waarde aan te pas- sen. Wanneer we een tijdje bezig zijn met een applicatie kan het gebeuren dat we code hebben geschreven die niet meer wordt aangeroepen. In ons voorbeeld zien we met de regels UnusedPrivateField en UnusedPrivateMethod dat we een variabele en methode hebben ge- maakt die helemaal niet worden aangeroepen. Deze code kunnen we dus rustig verwijderen.
We kunnen ook regels configureren, zodat we code richtlijnen en stan- daarden voor een project kunnen maken en toepassen op alle code. Denk bijvoorbeeld aan naamgeving van variabelen of het toevoegen van een copyright statement in de bron code. De regels FieldName en RequiredCopyright geven in ons voorbeeld aan dat we niet aan deze richtlijnen voldoen. De variabele naam voor het Logger object is een constante en de naam moet dan bestaan uit hoofdletters. Verder heb- ben we een specifieke regel geconfigureerd die kijkt of er een copyright statement in de code aanwezig is.
Het is mogelijk om bij het uitvoeren van CodeNarc op de code bepaalde regels te negeren. Allereerst kunnen we met een configura- tie bestand aangeven welke regels we wel of niet willen toepassen. Verder kunnen we ook de prioriteit definiëren voor een regel. Deze configuratie is beschreven in een Groovy bestand.
In de bron code zelf kunnen we met de annotatie @SuppressWarnings opgeven dat een bepaalde regel genegeerd kan worden voor een stuk code. Hierdoor worden we niet lastig gevallen in de rapportage met zaken waarvan we weten dat ze een regel niet volgen, maar dat we dat ook niet erg vinden voor dit specifieke stuk code.
We hebben nu een klein gedeelte gezien van de regels die CodeNarc ondersteunt. Maar het is niet moeilijk om zelf regels te schrijven. Voor een eigen regel moeten we een visitor klasse maken die de Abstract Syntax Tree (AST) van de code kan doorlopen. De AST bevat alle code
vlak voordat die gecompileerd gaat worden. We kunnen deze structuur bekijken en analyseren, zodat we weten of de code voldoet aan de door ons gestelde regels. De CodeNarc API bevat allerlei handige methoden waarbij we specifieke onderdelen van de AST kunnen bekijken en daar dan ook analyses op toe te passen.
Conclusie De conclusie is dat CodeNarc een erg nuttige tool is om toe te passen op projecten met Groovy code. Er is ook een plugin voor Grails beschikbaar, zodat we ook CodeNarc voor Grails projecten kunnen gebruiken. De standaard regels die beschikbaar zijn zorgen ervoor dat we makkelijk kunnen leren hoe we code moeten schrijven die voldoet aan de Groovy syntax, maar ook hoe we betere klasse implementa- ties kunnen maken. Voor specifieke regels voor onze projecten kunnen we de regels ook configureren, zodat we bijvoorbeeld een standaard naamgevingsconventie binnen het project kunnen gebruiken. Naast het configureren van de regels, is het niet moeilijk om zelf nieuwe regels te maken en toe te passen binnen een project. CodeNarc is hiermee een uitstekende code analyse tool om te gebruiken. •
Hubert Klein Ikkink
werkt sinds 1996 met Java en sinds
2008 met Groovy. Hij werkt op ver-
schillende projecten met Groovy/
kwaliteit van de geschreven code
goed is.
Wat is Uniface
Uniface is een modelgedreven en -gebaseerde ontwikkelomgeving voor het bouwen van bedrijfsapplicaties die er toe doen. Superpro- ductief, toekomstvast en veelzijdig inzetbaar. Je hebt tot zeven keer minder regels code nodig dan bij Java of .Net voor hetzelfde resul- taat. Uniface kent een open architectuur die goed toepasbaar is voor de bouw van moderne bedrijfssystemen, zowel voor RIA applica- ties voor de Cloud als voor geavanceerde Client/Server systemen. Uniface applicaties leven lang en laten zich eenvoudig transforme- ren naar nieuwe eisen, wensen en technologieën.
Uniface proberen? Als je de mogelijkheden van Uniface gratis en zonder verdere verplichtingen wilt uitproberen ga dan naar http://www.compu- ware.com/forms/uniface-trial.html en vul het aanvraagformulier in. Je krijgt dan de nieuwste Uniface versie voor drie maanden ter beschikking.
Ook als je Uniface al kent en je wilt graag snel een Rich Internet Applicatie bouwen, vraag dan een gratis download aan op boven- staand adres.
DESKTOP Theo Neeskens
In Uniface beginnen we met het bouwen van de informatie structuur van de pagina in een Dynamic Server Page. Daarop zetten we een dummy entiteit met knop om de gegevens op te halen, en een aantal velden om ze in te stoppen:
Deze structuur kopiëren we naar de Server Page Layout Editor. Hier zouden we de opmaak van de pagina nog kunnen verfraaien, maar de standaard opmaak volstaat voor dit voorbeeld:
Social Media koppelingen in Uniface Enterprise Systemen
Er zijn guru’s die zeggen dat je Social Media en Enterprise Systems niet mag vermengen. Ik ben het daar niet mee eens. Als jouw marketing manager denkt jullie omzet te kunnen vergroten door alle prijs verla- gingen in het artikelbestand automatisch op de Facebook pagina van je bedrijf te posten, dan zou ik daar zeker iets voor gaan bouwen. Voor de kosten hoef je het niet te laten. Je zou ook kunnen denken aan een koppeling tussen je Enterprise CRM systeem en LinkedIn. Dan kan je accountmanager nieuwe klanten automatisch uitnodigen om een connectie te worden.
Bij de verschillende Social Media worden verschillende technieken gebruikt. Veel voorkomende technieken zijn bijvoorbeeld REST webservices, JavaScript API’s en het autorisatieprotocol Oauth. Over het algemeen zijn de koppelingen goed gedocumenteerd en is er een forum beschikbaar om ervaringen uit te wisselen met andere ontwik- kelaars. Met een beetje geluk is er een library beschikbaar waar de basis protocollen voor je in geïmplementeerd zijn, wat het gebruik vanuit jouw programmeertaal vergemakkelijkt.
Als Uniface developer hebben we helaas nog niet de luxe dat er complete libraries voor ons gemaakt zijn. Maar de meeste basis protocollen zijn gelukkig vrij eenvoudig te implementeren. Om te laten zien hoe je dit kunt aanpakken leg ik hier uit hoe je een koppeling tussen een Uniface web applicatie en LinkedIn kunt maken. Hiervoor gebruik ik de Uniface JavaScript API die nieuw is in Uniface 9.5 die binnenkort op de markt komt. Ik heb geprobeerd het voorbeeld zo eenvoudig mogelijk te houden, zodat je goed kunt zien hoe de principes werken. Daarna zou het vrij gemakkelijk moeten zijn om het naar eigen inzicht uit te breiden.
LinkedIn In dit voorbeeld gaan we inloggen bij LinkedIn en enkele gegevens uit ons eigen profiel ophalen. Wij doen dit vanuit een webpagina die gebouwd is als Uniface Dynamic Server Page. We beginnen met het registreren van onze applicatie bij LinkedIn, zodat we een API key krijgen. NB: Voor het testen van je applicatie kun je een localhost URL gebruiken.
MAGAZINE
20
DESKTOP
In de HTML source moeten twee stukjes JavaScript opgenomen worden. In de Header moet een verwijzing komen naar de LinkedIn JavaScript API en de API key die je gekregen hebt bij het registreren van je applicatie bij LinkedIn. In de Body staat een stukje script wat er voor zorgt dat er een Login button getoond wordt, die na een geslaagde login vervangen wordt door Hello Voornaam Achternaam.
Als laatste hebben we dan nog een stukje code nodig om de gege- vens uit het LinkedIn profiel te halen en in de Uniface velden te zetten.:
Als we nu compileren en testen ziet de pagina er zo uit:
Als je op de “Sign in with LinkedIn” button klikt verschijnt er een pagina van LinkedIn. Wat daar op staat is afhankelijk van de situatie. Meestal zal dit een standaard login pagina zijn, gevolgd door een pagina waarop je toestemming aan de applicatie moet geven om jouw LinkedIn account te gebruiken. Ik krijg nu een ietwat andere pagina omdat ik al toestemming verleend heb, maar dit al een tijd niet meer gebruikt heb:
Nu ben ik ingelogd en LinkedIn heeft de button vervangen door een welkomtekst met mijn naam er in:
Als ik nu op de “Get your profile” button klik, worden enkele gegevens uit mijn LinkedIn profiel opgehaald en in de Uniface velden gezet:
En zo hebben we dus met een paar regeltjes code een koppeling gemaakt tussen een Uniface web applicatie en LinkedIn. Lees vooral de documentatie van LinkedIn over hun API om te zien hoe je dit uit kunt breiden tot een koppeling die zinvol is voor jouw business. •
magazine voor software development 21
Theo Neeskens
bij de Uniface Services afdeling van
Compuware. Met inmiddels 19 jaar
productervaring helpt hij Uniface ge-
bruikers wereldwijd met implemen-
online Uniface community. Bezoek
ook zijn blog op http://theunifaceuniverse.blogspot.com
Microsoft-specialisten Stel, je hebt een passie voor Microsoft. Je bent een
kei in applicatieontwikkeling en -architectuur. En je
wilt verder in je vakgebied. Dan is Sogeti het bedrijf
voor jou. Met 700 Microsoft-professionals behoren
we tot de grootste Microsoft-communities van
Nederland. Bovendien verwachten onze klanten
innovatie, zodat je echt al je kennis inzet. Wat ons
betreft wordt die kennis steeds breder en dieper;
we dagen je uit om het maximale uit jezelf te halen.
Bijvoorbeeld door je cursussen en opleidingen
aan te bieden. We zijn niet voor niets een van de
meest gecerti ceerde organisaties in de branche.
Qua omgeving kun je denken aan ALM, VSTS 2010,
.NET4.0, O ce 2010, SharePoint 2010, Azure en
BPOS. Terwijl de projecten enorm gevarieerd zijn.
Van BizTalk-implementaties en end-user BI-oplos-
singen tot de omvangrijkste integratie ooit van
SharePoint in Dynamics CRM.
JAVA-specialisten Als je passie hebt voor het Java vakgebied, dan
wil je natuurlijk ook werken bij het bedrijf met de
beste Java Community van Nederland. Bij Sogeti
ben je dan aan het juiste adres. Ruim 100 ervaren
Javanen werken bij Sogeti aan het realiseren van
complexe en innovatieve oplossingen voor haar
klanten. Aangezien vakmanschap bij Sogeti hoog
in het vaandel staat, wordt er veel tijd geïnvesteerd
in het vergroten van kennis en de persoonlijke
ontwikkeling van de Java professionals. Het behalen
van Java certiceringen is daar onlosmakelijk mee
verbonden. Sogeti heeft dan ook niet voor niets de
best gecerticeerde Java Community van Nederland.
Wil jij met jouw kennis en ervaring onze Microsoft
Community of Java Community versterken?
Neem dan gerust contact met ons op of kijk op
werkenbijsogeti.nl.
Wat kun je? Die vraag stelt ieder bedrijf met een vacature. Wie ben je? Die vraag stelt Sogeti
meteen daarna. We vinden het belangrijk dat je bij ons past. Want een ICT-er van Sogeti is
geen gemiddelde ICT-er. Het is er een met uitgesproken eigenschappen.
Gedreven. Resultaatgericht. En niet snel tevreden. Natuurlijk: plezier hoort erbij. Maar we
gaan op de eerste plaats voor de inhoud. Zo kennen klanten ons. Zo kennen we elkaar.
Als het een ICT-er is, zit hij bij Sogeti.
DELPHI Cary Jensen
Record Basics The traditional style of record definition is somewhat similar to an array, in that it can hold more than one data value. But there are a number of features that distinguish records from arrays.
In an array the various values are identified using an ordinal index. Records, by comparison, make use of named fields. Furthermore, arrays consist of a collection of elements that are all of the same data type (even if all elements of the array are variants). In records, the individual fields can be almost any valid Delphi type, including integers, Booleans, real numbers, object references, arrays, interfaces, and enumerations.
Declaring a Record Consider the following type declarations. Together, these types define a record type, TDog, that includes four fields: A double, an enumera- tion, a TDateTime, and a TObject reference.
type
constructor Create(Name: String);
TDog = record
Weight: Double;
Breed: TBreed;
Born: TDatetime;
Owner: TPerson;
end;
Using a Record Once you have defined a record type, it is easy to create an instance of that record. Simply declare a variable of that record type and use it. It is not even necessary to allocate memory for the record - Delphi does that for you. For example, the following code demonstrates how to declare and use a record of type TDog.
Records are data structures that hold one or more pieces of information. While records have been around since the earliest days of Pascal, they have taken on a much larger role in the most recent versions of Delphi. Today's records possess many features previously only found in objects.
This article begins with a brief overview of records. It continues with a discussion of features that have been added to records since Delphi 2005. This article concludes with a look at several of the important new record types that have been introduced to Delphi in recent versions.
For The Record
procedure TForm1.Button2Click(Sender: TObject);
...
Actually, it's not necessary to declare a record type in order to use a record. Instead, a variable can be defined as a record in its declara- tion. This might look something like the following:
procedure TForm1.Button3Click(Sender: TObject);
// ...
More Variations There are a couple of additional variations that are somewhat unique to records, and these are associated with enumerations and variant parts. Let's consider enumerations first.
In the TDog record type, Breed was declared as a field of type TBreed. An alternative would be to declare the Breed field to be an enumera- tion directly, without the TBreed declaration. Here is another record type declaration that uses this syntax:
type
MeetingWith: TPerson;
DELPHI
of a record were public. Since Delphi 2005, the same visibility directives that you can use in class declarations can now also be used in record declarations.
But Delphi 2006 is the version in which the really big changes were introduced, giving records many features previously reserved for classes, and greatly improving their utility in your Delphi applications. These features include methods, properties, constructors, class constants, class variables, class static methods, class properties, nested types, overloaded operators, and record helpers. Each of these features are consider in the following sections.
Methods and Properties A record's methods are functions and procedures associated with the record. Like their class cousins, a record's methods can access all of the other members of the record, including fields, properties, and other methods. Similar to the methods of a class, a record's methods have a reference to the record's instance through a variable named Self.
Record methods also permit overloading. When overloading a record's method, you follow the same rules that you follow when overloading the methods of a class. Specifically, the compiler must be able to distinguish between each overloaded version based on the signature of the method (including whether the method is a function or procedure). Record properties are also similar to their class counterparts. A record's properties can be implemented with read and/or write parts, and can use either direct access (reading and writing from fields of the record) or accessor methods (implementing reading and writing through specified methods of the record. Accessor methods permit a property to perform side effects).
The following is a simple example of a record with two fields (variables), a method, and three properties.
type
property Width: Double read FWidth write FWidth;
property Depth: Double read FWidth write FDepth;
end;
The methods declared in a record must be implemented (records do not permit abstract methods). Furthermore, after declaring a method in a record you can use class completion (Ctrl-Shift-C) to generate the necessary implementation stubs for your record's methods. The following is the implementation of the GetArea method of the TRectangle record.
function TRectangle.GetArea: Double;
end;
Record Constructors All records have an implicit, zero parameter constructor that is called when you attempt to use a record for the first time. If you want, you can add additional constructors. These constructors, however, must have at least one parameter, and must be distinguishable from any
MeedtingBy: TPerson;
end;
In the TAppointment record type, the DayOfWeek field is an enumeration, which is defined in the record type declaration directly.
Another interesting feature of traditional records is the optional variant part. A variant part is a conditional portion of the record structure that can hold variable pieces of information. The variant part, if present, always appear at the end of a record declaration.
For example, consider the following declaration of Delphi's TRect, which appears in the Types unit.
TRect = record
1: (TopLeft, BottomRight: TPoint);
end;
Using this syntax, you can use one or the other variant record struc- tures (four Longints or two TPoints, though you cannot mix them in an individual instance of a record). For example, the following code de- clares and assigns data to two TRect instances (which are identical):
var
r2.Top := 5;
r2.Left := 5;
r2.Bottom := 100;
r2.Right := 200;
There is a second syntax, in which the value of one of the record's fields determines which of the alternative structures the record uses. For example, consider the following record type declaration:
type
StartDate: TDate;
EndDate: TDate;
end;
In this record, when the Boolean field MilitaryService is assigned the value True the WhichService, StartDate, and EndDate fields are avai- lable. If MilitaryService is False, a single enumerated field, Reason, can be used.
Class-Like Records Beginning with Delphi 2005, records began to receive a major overhaul with the introduction of member visibility. Until this time, all members
MAGAZINE
24
DELPHI
other overloaded constructor based on their signatures.
The following shows the TRectangle record with an overloaded constructor (note that the overload directive was not required, but makes the code clearer). The implementation of the constructor follows in this code segment.
type
property Width: Double read FWidth write FWidth;
property Depth: Double read FWidth write FDepth;
constructor Create(Width, Depth: Double); overload;
end;
end;
Class Constants and Class Variables While each instance of a record has one memory location for each of its fields, class constants and class variables are shared between all instances of a given record type. A class constant is a constant value, and its declaration looks a lot like a regular declaration of a constant. The difference is that the class constant is a characteristic of the specific record type. The class constant can be read using a reference to an instance of the record type, or through the record type itself.
A class variable is a field that is shared by all instances of a particular record type. Changing the value of a class variable has the effect of changing the one memory location shared by the record type and all instances of it. Class constants appear within a const clause of a record declaration, and class variables appear within a class var clause. These clauses conclude at the end of the record declaration, or when a method, type, variable, property, constructor, visibility directive, or variant part is encountered.
The following record type includes two class constants and two class variables:
TRectangle = record
strict private
FWidth: Double;
FDepth: Double;
property Width: Double read FWidth write FWidth;
property Depth: Double read FWidth write FDepth;
constructor Create(Width, Depth: Double); overload;
end;
Class Static Methods and Class Properties Unlike classes, which have both class methods and class static methods, records support only class static methods (as far as class methods go). A class static method is one that can be called on an instance of a record or through a reference to the record type itself. Like the class static methods in a class declaration, a record's class static methods have no reference to Self, and therefore cannot access any other members of the class, other than other class static methods or class variables. Class properties are properties that can be referenced using an instance of a record type, or the record type itself. While class properties support both direct access and accessor methods (like normal properties), direct access can only employ class variables, and accessor methods must use only class static methods.
The following is a portion of a record type declaration that includes two class variables, a class static method, and two class properties. The implementation of the class static method follows.
type
class property PreferredMinWidth: Double
read FPreferredMinWidth write FPreferredMinWidth;
class property PreferredMinDepth: Double
read FPreferredMinDepth write FPreferredMinDepth;
end;
Nested Types A nested type in a record is identical to a nested type in a class declaration. A nested type is a type declaration internal to a record. The nested type is often a class type that is designed to act as a helper class. Specifically, it is designed to perform tasks related to the record in which it is declared.
The following is another record class segment, which includes a simple nested type declaration.
type
DELPHI
end;
property Width: Double read FWidth write FWidth;
property Depth: Double read FWidth write FDepth;
end;
Operator Overloading One additional feature added to records that is not shared by classes is operator overloading. In short, you can explicitly define what happens when an operator is applied to a particular record (unary operators) are to two records (binary operators). For example, you can define what happens when two of your records are added together using the addition (+) operator, or what happens if you implicitly cast your record to another type.
There are almost 30 operators that can be overloaded. These operators are shown in Listing 1.
Listing 1 Record operators that can be overloaded
To overload one of these operators, you implement the specified method name using the class operator syntax (instead of function) in your record type definition. You must also define the type of value that the operator will return. For those operators that are declared to return a Boolean value, the operator must return a Boolean value. All other operators can return whatever type is appropriate for that operator. In other words, a non-Boolean operator can return a value other than the record type.
The following code segment includes a portion of the TRectangle class with an overloaded addition operator, the implementation of this operator overload, and an event handle that uses the operator.
type
//...
end;
begin
end;
Record Helpers Like classes in Delphi 2005, records can also have helpers. Record helpers serve essentially the same purpose as class helpers, though they only apply to records. Specifically, record helpers permit you to attach additional methods, properties, and class variables to an existing record. Record helpers can also replace existing methods of a class, if they use the same name and signature, since methods of a record helper supercede those of the record they are helping.
While the use of class helpers is largely discouraged, record helpers can play a role that cannot be provided through any other means. Specifically, record helpers provide the only mechanism for extending an existing record type. Classes, on the other hand, support inheritance. As a result, it is often better to descend a new class from an existing class, and introduce new methods and properties in the descendant than to use a class helper.
Record helpers have the same limitations as class helpers. A given record can be supported by only one record helper. If there is more than one record helper for a given record, the record will employ the record helper that is closer in scope.
The following code shows the declaration of a record helper for the TRectangle record, along with the implementation of the single method declared within the record helper. Notice in the GetMaxArea implementation that Self refers to the record instance.
type
function GetMaxArea: Double;
begin
ShowMessage(FloatToStr(a.GetMaxArea));
end;
Records Versus Classes At this point you might be inclined to think that the enhanced record syntax makes records nearly identical to classes, making it difficult to
MAGAZINE
26
DELPHI
choose between them. The truth is that there are very significant differences between records and classes, and these differences can help you decide which to use in a particular situation.
First of all, records are allocated on the stack, as long as they are not declared globally or managed using New and Dispose. Class instances, by comparison, are allocated on the heap.
This has a significant impact on memory management. Specifically, while classes that do not have an owner must be explicitly freed, memory allocated for record instances is automatically freed when the record goes out of scope merely by its data being removed from the stack. Of course, if your record creates class instances during its lifecycle, that memory must be managed by you or your record, or a memory leak may exist. This is made a bit more difficult since records do not support destructors.
Another significant difference between classes and records is that you do not need to call a record's constructor, while a class instance must be explicitly created. You can declare a variable of a record type and then immediately use it. In this case, Delphi will call the zero parame- ter constructor for you.
You are still free to call a record's constructor if you want. In fact, if you've declared one or more additional constructors, it is probably because you want to create your record in a particular fashion, and you can do so by calling one of those overloaded constructors.
Another major difference between records and classes is that records do not support inheritance. A record never descends from an existing record. Similarly, records cannot implement interfaces (though they may have fields or properties of interface type, but that is different). The bottom line here is that records do not support polymorphism. A corollary of this is that record methods are necessarily static. Records do not support virtual, dynamic, or abstract methods.
As you learned earlier, records can also include a variant part. A variant part permits a record to hold data that is specific to its nature, and may vary from record instance to record instance. All instances of a class have the same set of members, regardless of their data.
Finally, records are value types, as opposed to reference types. Consider the following code:
var
a.Width := 5;
a.Depth := 5;
b := a;
The TRectangle named b in this code segment is a completely new record that contains a copy of the data held within record a. By comparison, if TRectangle was a class type, following the assignment of variable a to variable b, variable b would point to the same memory address as a.
Finally, records support operator overloading, while classes do not. Operator overloading provides you with a rich tool for managing exactly what happens when records are used in expressions, and the results can get very interesting.
Examples of Useful Records in Delphi Record types are playing an increasingly important role in the latest
versions of Delphi, and this is due in large part to the differences between record types and class types described in the preceding section. Let's consider a few of the more significant record types. Delphi 2009 saw the introduction of the System.TMonitor type. TMonitor is a record that can be used to acquire and manage a lock on any TObject. It provides a convenient and powerful synchronization mechanism for multithreaded applications. A major new layer of runtime type information (RTTI) was introduced in Delphi 2010. The principle type for working with the new RTTI, TRTTIContext, is a record type.
Additional records types introduced in Delphi 2010, and further enhanced in Delphi XE, include TFile, TPath, and TDirectory. These types, which are declared in the IOUtils unit, are record types.
Summary It is no longer safe to assume that the entity you are calling a method on, or are reading a property from, is an object. It might be a type of record. Indeed, records types posses a unique blend of features that make them better suited for a variety of situations in which you would have previously used a class type. •
Cary Jensen
author of more than 20 books on
software development and winner of
the 2002 and 2003 Delphi Informant
Reader's Choice Award for Best
Training. A frequent speaker at
conferences, workshops, and semi-
nars throughout much of the world, he is widely regarded for his
self-effacing humor and practical approaches to complex issues.
Cary's company web site is at: http://www.JensenData
Systems.com. Cary has a Ph.D. from Rice University in Human
Factors Psychology, specializing in human-computer interaction.
COBOL is terug: Visual COBOL R3 Om COBOL gebruikers in staat te stellen hun systemen te migre- ren naar nieuwe technologieën en moderne platforms, lanceert Micro Focus Visual COBOL R3. Met deze oplossing krijgen ontwikkelaars de mogelijkheid om COBOL eenvoudig uit te breiden naar de nieuwste applicatie-ontwikkelomgevingen zonder de nood- zaak om de code te herschrijven.
Met Micro Focus Visual COBOL R3 is COBOL toegankelijk voor een brede reeks platforms. Naast Windows, UNIX, Linux en .NET zijn COBOL-applicaties ook voor het eerst inzetbaar in de Java Virtual Machine- (JVM) en Microsoft Azure-cloud-platforms. Ontwikkelaars hebben de keus uit Visual Studio 2010 of Eclipse als geïntegreerde ontwikkelomgeving. Zij kunnen zonder platform- specifieke ingrepen tevens kernapplicaties in COBOL vanuit één bron op verschillende platforms inzetten…
Het volledige artikel is te lezen op: http://www.release.nl/Nieuws/70780/COBOL-is-terug--Visual- COBOL-R3
magazine voor software development 27
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.
2QJHKLQGHUGGRRUUHGXQGDQWLHEDQGEUHHGWHRIGHEHSHUNLQJHQYDQXZVHUYHUFRQÀJXUDWLH
Dat is Cloud Power.
Probeer* Windows Azure gratis. Ga naar microsoft.nl/azure
Download de gratis app op http://gettag.mobi
figure 1. System.DirectoryServices architecture, taken from http://msdn.microsoft.com/en-us/magazine/cc135979.aspx
In .NET Framework 1.1 there was only System.DirectoryServices. In .NET Framework 2.0 they've added Active Directory which provides a high level abstraction model for things like forest, domain, site etc. They also added the Protocols API. This API provides access to an Active Directory through LDAP or DSML. In the .NET Framework 3.0 they've added the AccountManagement API. The goal of this API was to abstract away the underlying principal store. It shouldn't matter if you talk to Active Directory Domain Services, Active Directory Lightweight Directory Services or your local computer store (SAM).
If you want to read more details about the setup of this namespace, i'd suggest to take a look at http://msdn.microsoft.com/en-us/ library/ms180826(v=VS.100).aspx Querying Active Directory is not really hard and a lot of examples are on the internet. One problem that is relatively undocumented though is that when you query a user for its groups it will only return the groups where the user is directly a member of. Say you have the following structure:
AD forest root App_Group_1
App_Group_2 User 1
When querying User 1 for its groups, it will only return App_Group_2
Querying nested groups in Active Directory A lot of companies for which we write software have the need to integr