Borland Delphi 8 for .NET |
Dit artikel introduceert Borland's Delphi 8 for .NET, en laat zien hoe we .NET toepassingen kunnen ontwikkelen met Borland's nieuwste IDE voor het .NET Framework. Omdat de meeste lezers op de hoogte zullen zijn van de mogelijkheden van Visual Studio.NET, zal dit artikel met name ingaan op de verschillen en zaken die afwijken - zowel in positieve als wat minder positieve zin.
Delphi 8 for .NET
Delphi 8 for the Microsoft .NET Framework is de officiële naam, maar de meeste ontwikkelaars noemen het gewoon Delphi 8 of Delphi 8 for .NET (alleen Delphi for .NET is niet volledig, want bij Delphi 7 zat eind 2002 al een Delphi for .NET preview command-line compiler, die echter niet te vergelijken is met wat nu als Delphi 8 for .NET beschikbaar is).
Alhoewel Delphi 8 for .NET een relatieve nieuwkomer is op het .NET Framework, geldt dat niet voor de taal Delphi zelf.
Delphi 1.0 werd op Valentijns dag in 1995 gelanceerd, en was in feite de 8e generatie van Borland's Turbo Pascal compiler die het eerste daglicht zag in het begin van de 80-er jaren.
Met Delphi 8 is de compiler zelf toe aan versie 16 (ook de Delphi compiler in C++Builder en Kylix hebben gezorgd voor aanpassingen aan het versienummer).
Vanaf Turbo Pascal versie 1.0 t/m Delphi versie 2.0 is trouwens niemand minder dan Anders Hejlsberg de architect geweest - voor hij naar Microsoft vertrok om daar een belangrijke rol te spelen in de ontwikkeling van de taal C# en het .NET Framework zelf.
Lezers kunnen overigens de Trial versie van Delphi 8 for .NET downloaden van de Borland website.
Migratie en Portabiliteit
Alhoewel het .NET Framework erg belangrijk is voor Borland, zijn er nog veel ontwikkelaars die Delphi 7 gebruiken om 32-bit Windows toepassingen te bouwen en te onderhouden, en hier lijkt voorlopig nog geen einde aan te komen.
De volgende versie van Delphi - versie 9 - zal ontwikkelaars zelfs in staat stellen om vanuit één omgeving zowel Windows als .NET toepassingen te bouwen.
Zover is het echter nog niet, en op dit moment moeten we Delphi 7 nog gebruiken om Win32 toepassingen te bouwen (of te onderhouden), want Delphi 8 (for .NET) kan "alleen" maar .NET toepassingen produceren.
Met nog wel een extraatje - zie daarvoor de paragraaf over Assemblies en Libraries.
WinForms
Delphi 8 for .NET biedt net als Visual Studio de mogelijkheid om WinForms toepassingen te bouwen.
De WinForms Designer lijkt niet alleen als twee druppels water op die van Visual Studio, maar is daadwerkelijk de designer van Microsoft.
Dat heeft als voordeel dat gebruikers van Visual Studio zonder al teveel problemen de Trial versie van Delphi 8 for .NET kunnen gebruiken om eens te proeven hoe het werkt.
Hierboven zien we de Object Inspector, WinForms Designer, een Tool Palette met componenten en rechtsboven een venstertje waarin je met de Project Manager, Model View (daarover later) of the Data Explorer kan werken.
ADO.NET en BDP
Om met databases te werken in Windows Forms of Web Forms toepassingen kunnen we ADO.NET gebruiken.
Ook Borland's Delphi 8 for .NET ondersteunt ADO.NET, alhoewel je niet de design-time wizards zult aantreffen die wel in Visual Studio.NET aanwezig zijn.
Het gebruik van ADO.NET gaat in Delphi 8 for .NET dan ook wat moeizamer.
De reden is het feit dat Borland een eigen laagje over ADO.NET heeft geschreven, en onder de naam Borland Data Providers aan Delphi 8 for .NET heeft toegevoegd.
Het ADO.NET pattern is gevolgd, dus we hebben nu een BdpConnection, BdpDataAdapter, BdpCommand, BdpCommandBuilder, etc.
die met de standaard .NET DataSet, en DataView kunnen werken op de manier zoals we die gewend zijn.
Het grootste verschil zit hem in het feit dat de BdpConnection door middel van het aanpassen van de ConnectionString ook van database type zelf kan wijzigen.
De overige BdpComponenten zullen niet hoeven te wijzigen, en zijn 100% database onafhankelijk (net als de .NET DataSet zelf bijvoorbeeld).
Borland levert met Interbase zelf ook een database, maar heeft er meer belang bij te zorgen dat Delphi gebruikt kan worden in combinatie met alle grote spelers in de markt.
Standaard zitten er al vijf BDP drivers in Delphi 8 (voor DB2, Interbase, MS Access, SQL Server, en Oracle), en er zijn al enkele third-party aanbieders die ook hun eigen BDP drivers hebben geschreven en aanbieden.
Dit is interessant voor ontwikkelaars die een .NET toepassing willen schrijven zonder daarbij bij voorbaat al voor een bepaalde database te kiezen.
In afbeeling 2 is de Connections Editor te zien waarmee de ConnectionString property van de BdpConnection component te configureren is.
Voor iedere aanwezigde DBMS driver (opgesomd in bestand BdpDataSourcex.xml) is al een voorbeeld connectie opgenomen.
De sectie met ProviderSettings in afbeelding 2 geeft aan welke properties op basis van het DBMS zijn ingesteld, en zelf kun je dan nog de Connection properties en eventuele Options instellen.
Een andere feature van de Borland Data Provider componenten is de mogelijkheid om "live" data tijdens design-time te vertonen (ook in ASP.NET pagina's met de DB Web controls).
VCL for .NET
Naast ondersteuning voor Windows Forms toepassingen, kunnen we met Delphi for .NET ook safe en managed VCL for .NET toepassingen ontwikkelen.
VCL staat hier voor de Visual Component Lilbrary die al sinds 1995 onderdeel is van Delphi 1 t/m 7.
De controls in de Windows.Forms hierarchy lijken sterk op de controls in de VCL hierarchy - er is een duidelijke overeenkomst.
Er zijn echter ook een aantal verschillen, met name in de properties en sommige events of methoden.
De VCL kent bijvoorbeeld aan ieder component zowel een Parent als een Owner toe (de Parent is de visuele vader, de Owner beheert het geheugen), iets wat niet onder WinForms gebeurt.
De verschillen tussen WinForms en VCL zijn niet dramatisch, en voor een ontwikkelaar redelijk snel te leren, maar voldoende om bestaande Delphi broncode niet zonder meer om te zetten naar een vergelijkbare WinForms versie.
Vandaar de inspanning van Borland om een VCL for .NET te bouwen, inclusief een eigen VCL for .NET Designer.
VCL for .NET is niet een laag op WinForms, maar een laag op de Win32 API.
Het biedt dezelfde "interface" als de VCL voor Windows, maar dan alleen maar gebruikmakend van safe, managed code (even los van de Win32 API aanroepen).
Een VCL toepassing is te migreren naar een VCL for .NET toepassing door alle stukken "unsafe" code om te schrijven of aan te passen.
De weg terug is zelfs eenvoudiger: een VCL for .NET toepassing kan met Delphi 7 gecompileerd worden tot een Win32 toepassing (mits geen gebruik is gemaakt van de Delphi taaluitbreidingen die in Delphi 8 zijn geïntroduceerd).
Van de ruim 100 VCL componenten hebben slechts een paar dozijn de overstap naar .NET en VCL for .NET (nog) niet meegemaakt.
De volledige source code van VCL for .NET meegeleverd met Delphi 8 for .NET, en ook enkele (maar nog zeker niet alle) third-party leveranciers brengen .NET edities uit van hun Delphi componenten.
Onder de VCL componenten die .NET (nog) niet gehaald hebben zit o.a.
de ondersteuning om databases via ADO te benaderen.
Gelukkig bevat de VCL een flink aantal (alternatieve) manieren om met databases te werken.
Zo is er de Borland Database Engine (BDE) met ondersteuning voor dBASE en Paradox tabellen - nu ook voor .NET.
Onder Windows was hier ook nog een SQL Links laag bij om met SQL Server, DB2, Oracle, Interbase, etc.
te werken, maar deze technologie is afgeschreven, en niet meer beschikbaar onder .NET (of de volgende versies van Delphi).
De gedoodverfde vervanger van BDE/SQL Links heet dbExpress, en is er in Windows en Linux smaken.
En nu ook in een .NET variant.
Via dbExpress kunnen we met SQL Server, DB2, Oracle, Interbase en onder .NET ook Sybase werken.
Daarnaast is ook Interbase Express (IBX) in een .NET variant aanwezig.
VCL vs. WinForms
De VCL for .NET en WinForms componenten leven naast elkaar - ieder in zijn eigen wereld.
VCL for .NET componenten kunnen niet in WinForms projecten gebruikt worden - alhoewel "normale" Delphi classes uit de RunTime Library (RTL) dat uiteraard wel kunnen.
WinForms controls kunnen wel in VCL for .NET projecten gebruikt worden, doordat Delphi 8 for .NET daar een speciale "wrapper" omheen kan genereren.
Net als het importeren van een COM object in Win32 als het ware.
ASP.NET 1.1
Delphi 8 for .NET bevat ondersteuning voor ASP.NET, zowel voor het bouwen van ASP.NET Web Services als ASP.NET Web Forms toepassingen.
Wie ASP.NET wil combineren met ADO.NET in Delphi 8 for .NET, komt er wederom achter dat er meer ondersteuning aanwezig is voor de Borland Data Providers.
Daarnaast heeft Borland een verzameling DB Web voor ASP.NET Web Forms toegevoegd.
Dit zijn componenten die het werken met databases ASP.NET Web Forms vereenvoudigen; een hoop zaken worden automatisch gedaan of makkerlijker gemaakt (zoals de automatische data binding, navigatie van het ene record naar het andere binnen een DataSet, edit/update en paginering binnen een DataGrid, etc.).
De DB Web controls zijn eenvoudig te deployen, en ook bruikbaar binnen andere (ASP).NET ontwikkelomgevingen (alhoewel ze niet los te koop zijn).
De volledige source code van de DB Web controls is ook aanwezig, deze keer in C# geschreven.
Assemblies / Libraries
We kunnen natuurlijk ook .NET assemblies bouwen met Delphi 8 for .NET.
Dit kan zelfs op twee manieren: via packages en via het library keyword.
Een Delphi package is de aanbevolen manier om .NET assemblies te bouwen, die vervolgens door andere .NET ontwikkelomgevingen (en toepassingen) gebruikt kunnen worden.
Hierbij moeten we dan wel de benodigde afhankelijkheiden meeleveren, zoals bijvoorbeeld de Borland.Delphi.dll assembly met de system unit van Delphi.
Deze en enkele tientallen andere Borland.Delphi assemblies kunnen vrij gedistribueerd worden door iemand die een Delphi 8 licentie bezit (dus iemand die Delphi 8 heeft gekocht).
Optioneel kun je er ook voor kiezen om alle Borland.Delphi assemblies mee te linken in de package, teneinde een grote maar opzichzelfstaande assembly op te leveren.
Dit kun je ook met executables zelf doen, waardoor je het aantal te deployen bestanden kunt terugbrengen tot slechts één (die dan wel groot is, omdat alle benodigde Borland.Delphi assemblies statisch meegelinkt zijn).
Een van de redenen waarom je dit überhaubt zou willen doen is de nog niet volledig dekkende licentieregeling die op dit moment wel een Delphi 8 ontwikkelaar in staat stelt om Borland.Delphi assemblies te distribueren, maar niet de ontwikkelaar die geen Delphi 8 bezit.
Stel de Delphi 8 ontwikkelaar X maakt een assembly A die Borland.Delphi.dll nodig heeft.
Een ontwikkelaar Y die zelf geen Delphi 8 bezit kan assembly A kopen en krijgt daarbij de Borland.Delphi.dll die nodig is om assembly A te gebruiken.
Tot zover geen probleem.
Echter, als ontwikkelaar Y een toepassing (component, assembly of wat dan ook) bouwt en wil deployen of verkopen aan een ander, dan komt het probleem om de hoek kijken dat ontwikkelaar Y officieel geen permissie heeft om de Borland.Delphi.dll te deployen.
Natuurlijk is het niet de bedoeling dat ontwikkelaar Y wordt beperkt in zijn mogelijkheden, en Borland is bezig met het aanpassen van de licentietekst.
Het alternatief voor de package is een library. Deze mogelijkheid is een overblijfsel uit de Win32 wereld, en biedt de mogelijkheid om een Dynamic Link Library te bouwen. Met Delphi 8 for .NET krijg je een .NET assembly, maar dan eentje waarbij op voorbaat alle afhankelijkheden meegelinkt zijn (dus één grote monolitisch IL-bestand). Dit heeft als voordeel dat iedere ontwikkelaar die geen Delphi 8 bezit alleen maar deze grote assembly hoeft te gebruiken en deze zonder problemen kan deployen. Behalve dan Delphi 8 ontwikkelaars zelf, die tegen het probleem aanlopen dat de Borland.Delphi.System namespace zowel in de grote assembly is opgenomen, als iedere Delphi 8 toepassing die je wilt bouwen. En dat levert foutmeldingen op vanwege o.a. de dan dubbele globale data definities. Waarom dan toch library gebruikt? Eigenlijk alleen vanwege een andere eigenschap, namelijk de mogelijkheid om de code binnen de library als "unsafe" te markeren. Dat levert dan een assembly op die welliswaar unsafe is, maar te gebruiken is vanuit een .NET toepassing, alsmede vanuit een Win32 toepassing. Dezelfde binary .NET assembly dus. Dit is geen source code compatibilitiet (dezelfde source code die tot een Win32 DLL of een .NET assembly kan leiden), maar binary compatibiliteit, waarbij dezelfde binary door zowel een .NET executable als een Win32 executable gebruikt kan worden. Het grote voordeel van deze mogelijkheid is dat je als Delphi ontwikkelaar op dit moment dus code kunt ontwikkelen die nog zowel binnen Delphi 7 (Win32) toepassingen te gebruiken is (als DLL), maar ook al binnen .NET toepassingen te gebruiken is als (unsafe) assembly - en dan niet alleen vanuit Delphi 8 for .NET, maar ook vanuit Visual Studio.NET en andere .NET ontwikkelomgevingen. Bekijk als voorbeeld eens de code in Listing 1 (HashPasswordUnit.pas). Dit is unit van een Delphi 8 library assembly, die met de {$unsafecode on} compiler directive gemarkeerd is, waardoor PEVerify aangeeft dat hij niet safe is. De assembly maakt gewoon gebruik van de eigenschappen van het .NET Framework, bijvoorbeeld om een password te encrypten via de FormsAuthentication.HashPasswordForStoringInConfigFile uit System.Web.Security. De met Delphi 8 for .NET gecompileerde assembly is echter te gebruiken in vanuit een Delphi Win32 toepassing (gecompileerd met Delphi 2 t/m 7) te zien in Listing 2 (Win32Client.dpr), alsmede vanuit een .NET toepassing, zoals een C# toepassing. Merk op dat de code in Listing 1 alleen maar functies laat zien die geëxporteerd worden, en geen classes. Dat is iets wat in een Win32 DLL normaal was, maar de meeste .NET ontwikkelomgevingen zijn het meer gewend om classes te importeren en te gebruiken, en geen globale functies (of variabelen) meer. Om daarin te voorzien wordt door de Delphi 8 compiler een impliciete class genaamt "Unit" toegevoegd om vervolgens daarin alle globale functies en eventuele variabelen in op te bergen. Op die manier kunnen ook C# en andere .NET ontwikkelaars toch zonder problemen bij de anders globale methoden komen. Overigens zijn globale routines gewoon mogelijk binnen de CLR, dus het is niet zo dat Delphi iets zou doen wat niet mag.
Enterprise Core Objects
De Architect editie van Delphi 8 for .NET bevat met Enterprise Core Objects (ECO) ondersteuning voor het zogenaamde model driven application development.
Dit houdt in dat er op basis van UML diagrammen (die je zelf kunt ontwerpen in de UML Designer) code gegenereerd wordt, alsmede een object model dat opgeslagen kan worden als XML bestand of in een database (zoals SQL Server of elke andere database die door de Borland Data Providers kan worden aangesproken).
Er hoeft dus geen aparte vertaling met de hand meer plaats te vinden van het ontwerp (model) naar de source code, en het ontwerp en de code lopen altijd synchroon.
In afbeeling 3 is een voorbeeld model te zien in de UML Designer.
We kunnen daar classes, relaties (associations), overervingen, notes en andere links toevoegen.
Een class kan zowel attributen als operators hebben.
Om de objecten uit de EcoSpace te gebruiken kunnen we Object Constraint Language (OCL) expressies samenstellen.
Hiervoor is Delphi 8 for .NET uitgerust met een OCL editor.
ECO bevat elementen van Together en Bold, twee bedrijven die vorig jaar door Borland zijn overgenomen, en waarvan de gevolgen dus zichtbaar worden in de Borland ontwikkelomgevingen. Een eerste versie van ECO was ook al te zien in C#Builder, en de editie die bij Delphi 8 for .NET aanwezig is, heeft al weer wat nieuwe mogelijkheden. Er blijven wel nog wat wensen over: op dit moment is het namelijk nog niet mogelijk om het object model (de zgn. EcoSpace) als multi-user database te benaderen, en ook de mogelijkheden om er een multi-tier server van te bouwen zijn daarmee nog niet aanwezig. Dit staat als aandachtpunt op de wensen-lijst, maar het is nog niet bekend wanneer deze extra functionaliteit beschikbaar zal zijn.
Extra Tools
Op de Delphi 8 for .NET CD-ROM staan nog een aantal aanvullende tools en hulpmiddelen, zoals Interbase 7.1, de Wise Owl Demeanor Obfuscator, Component One Studio Enterprise (met een licentie voor één kwartaal upgrade), StarTeam, CaliberRM, SQL Server Developer Edition (MSDE), en er zit ook een CD-ROM bij met een developer editie van IBM's DB2 UDB.
Samenvatting
Borland Delphi 8 for .NET is een volwaardige .NET ontwikkelomgeving die niet alleen de mogelijkheid biedt om nieuwe .NET toepassingen te bouwen (WinForms, Web Forms, etc.) maar ook Delphi 7 ontwikkelaars in staat stelt om hun bestaande code geheel of gedeeltelijk naar .NET over te hevelen.
Voor visuele zaken geldt dat VCL for .NET het grootste deel van de bestaande VCL (voor Win32) onder .NET beschikbaar maakt.
Behalve migratie van code, is de reverse P/Invoke (unsafe) assembly een extra mogelijkheid om nieuwe functionaliteit zowel nog aan bestaande Win32 als nieuwe .NET toepassingen toe te voegen.
De Borland Data Providers bieden enkele voordelen boven ADO.NET, maar wie toch ADO.NET wil gebruiken zal merken dat daar nog weinig design-time ondersteuning voor in Delphi 8 for .NET zit.
Het bouwen van .NET Compact Framework (CF) toepassingen is overgens nog niet mogelijk met Delphi 8 for .NET.
Hiervoor moeten we nog Visual Studio.NET gebruiken, maar Microsoft en Borland werken hard samen om dit ook mogelijk te maken voor Delphi ontwikkelaars.
Ik verwacht zelf een groeiend belang van het Model Driven Application development model, en Enterprise Core Objects in Delphi 8 for .NET kan hier een leuke rol in gaan spelen.
Borland Delphi 8 for .NET is in drie edities beschikbaar: Professional, Enterprise en Architect.
Referenties
Wie nog vragen of opmerkingen heeft, kan die altijd per e-mail aan mij kwijt. Wie op de hoogte wil blijven van de laatste ontwikkelingen zou daarnaast zeker eens moeten overwegen om mijn Delphi for .NET clinic bij te wonen.