![]() |
Bulletin of Applied Computing and Information Technology |
|
|
Using a third Party Language with Microsoft’s .NETAbstractIn addition to the inevitable hype, Microsoft’s .NET initiative has introduced several interesting technical features such as the move from APIs to namespaces and the integration of different programming languages. The .NET Framework will allow developers to use at least sixteen languages in addition to Microsoft’s mainstream VB and C# . Of particular interest to the writers is that Borland have made available a pre-release version of Delphi 7 for .NET and intend to release more products aimed at .NET. The writers took a relatively simple Web application and built it two ways, using VB with ASP.NET and using Delphi as a scripting language for ASP.NET. Clearly .NET offers many “fresh fields” for language investigations. Although the two chosen languages are quite similar (and Delphi is still preview ware), we were able to arrive at some practical and useful comparisons. KeywordsProgramming language integration, ASP.NET, .Net framework 1. IntroductionThis paper describes an investigation into the intriguing concept of language agnosticism introduced with Microsoft’s .Net Framework. A small classic ASP web application scripted with VB was converted to ASP.NET using two different scripting languages, VB.Net and the Delphi for .Net preview. In comparing the two approaches we must be aware that at the time this was undertaken (February – April 2003), Visual Studio .Net was a mature and sophisticated development environment, whereas the Delphi preview had no IDE and was not a production release. Was it actually possible to invade Microsoft’s .Net initiative with a foreign language? Published documentation said it was, but we wanted to try it (and learn about .Net). 2. Convert or Rewrite?Any system conversion sits on a continuum ranging from a statement-by-statement translation to a significant rewrite. Due to the improved features of ASP.NET such as server controls and true object orientation, the predominant advice on converting classic ASP to ASP.NET is to rewrite if at all possible. We could find no documented precedent for converting classic ASP to Delphi for .Net so we evolved our own method. Ultimately, the two conversion approaches were situated at the extremes of the continuum. 3. The Original Classic ASP ApplicationThe application allows users of the site to create a personalized grocery shopping list that would always give them the cheapest possible grocery bill. This requires obtaining pricing information for common items from each of the local supermarkets. The original implementation of the application was a stereotypical prototype, thrown together extremely quickly, with little thought for future expansion. The database has six tables and approximately eight classic ASP pages. This initial implementation was as simple as an ASP application could get: · no use of custom COM objects, · no use of output caching, · use of the Access MDB format for the data layer. Essentially it was vanilla ASP, pages were POST-ing to themselves for validation, MS Access was used for the underlying database technology and generally, the application was considered ready for deployment. 4. Conversion to VB.NETA strategic decision was made to rewrite the application according to generally accepted best practice, or at least, better practice. This involved: · the move to a three-tier architecture, · the use of partial page output caching where appropriate, · the use of server controls and code behind forms, · the use of custom controls where appropriate, · the conversion of database technology to SQL Server 2000 utilizing stored procedures. The implication of this strategy required a complete redevelopment of the application from the data layer up. It was patently obvious to the authors that the existing code would be of no use whatsoever. In fact, the only salvageable items from the existing system were the graphics, style sheet, database table structure, and use cases. Choosing a Microsoft language for development yielded two primary benefits. The first advantage was being able to use the Visual Studio .Net IDE for Web application development. For a beginner in the ASP.NET world, the added productivity provided by the excellent debugging facilities was invaluable, as was IntelliSense for assisting with navigating the extensive class libraries. Secondly, the quality of support available for ASP.NET development is impressive. The IBuySpy store and portal products provided by Microsoft as examples of best practice present a significant foundation for ASP.NET development using three-tier architecture. The .NET community as a whole is likewise exceptional, providing guidance and code samples in a timely fashion to anyone who asks. The NZ.NET User Group’s list-server is a good example, see http://www.dot.net.nz/. 5. Conversion to DelphiWe used the third update of the Delphi preview dated 12 February 2003. Borland’s Delphi for .Net documentation is sufficient for a preview but unfortunately for us, completely ignores ASP.NET. It is aimed at the general .Net Framework. There are examples of Delphi ASP.NET scripting on http://dotnet.borland.com/ and http://www.drbob42.com (Bob Swart) and these were invaluable. A site dedicated to Delphi ASP.NET scripting, http://www.aspxDelphi.net/ (Zarco Gajic) has converted the IbuySpy e-commerce shop to Delphi and offer to sell their converted code and expertise. Both Bob Swart and Zarco Gajic answered emails promptly and were extremely helpful. One question put to the New Zealand Delphi User Group mailing list received no response. Another unlikely source of assistance was the help within Visual Studio .Net, particularly for C#. Without an IDE, source files were edited with NotePad. The compilation process was initiated by requesting the page in a browser. The Web server (IIS) would then invoke the compiler(s) and either display the page or an error report. The starting point was to take the original home page, rename it with a .aspx extension and convert it to .Net without any .Net features, still using VB and the Access database. This involved adding <%@ headers to specify the page language and imported namespaces, declaring all variables with “Dim”, removing “set” and “let” instructions and changing all “.createobject() to “New objectType()”. Once this ran under .Net, the VB code was converted to Delphi. This was firstly a syntax change from VB to Pascal. It seemed that Delphi code could not be “inline” so all code was placed in the Page_Load procedure and the HTML constructed by setting the innerHTML of <div> tags. Other changes involved adding the “.get” method to Request.Form() changing session array indexing from ( ) to [ ] and identifying various methods and properties using the Visual Studio help. The Web.config file contents had to be changed to set the compiler language and to add “DelphiProvider” as an assembly. After wrestling with file and Web server access permissions on Windows 2000 Server, we also got “code behind” to work, which is a tidier way to separate HTML and code. 6. Sample ScriptsThree sample scripts are in the appendices. Each sample covers the same task; it extracts and presents the product categories from the database. · The original Classic ASP sample is in appendix A. Note the mix of inline script and HTML. · The Delphi for .Net sample is in appendix B. The script is all in the Page_Load procedure and there is only one line of HTML at the end. · The VB .Net sample is in appendix C and is in three sections. The first point that the VB .NET app encounters the product list is through its inclusion as a custom control in the Default.aspx file. The control itself is described in the _Menu.ascx file, and finally, the relevant code in the ProductsDB.vb file. 7. ConclusionThe documentation said language integration could be done, and we proved this to be true by getting the Delphi conversion working. Visual Studio .Net is easy to use and highly productive. The freely available samples like IbuySpy and the .Net developer community make problem solving a breeze. Using Delphi for .Net was more difficult, but once the first page was converted, the remainder were straightforward. When we set out we naively and optimistically imagined we would evaluate this exercise in several ways. Two of these evaluations proved impossible: comparison of IDE’s and comparison of the intermediate code. With no IDE for Delphi we cannot reach any conclusion although rumour has it Delphi 8 planned for release at the end of 2003 will include .Net in its IDE. We could not compare intermediate code because Visual Studio creates a .DLL file and the temporary files created by the Web server were a completely different format. We are continuing to try to seduce Visual Studio .Net to build the .pas files and are also investigating the free command line build program, NAnt. Knowing that using a third party language with .Net is viable, we need to address the question of why a developer would need to do this. Is there anything wrong with C++, VB or C#? There are two situations where language choice is useful. These are where code exists written in a .Net language, that code can be re-used relatively easily and languages designed for specific problem areas, which make them the most logical choice (horses for courses). It is ironic that Microsoft, a company regarded by many as monopolistic, has made its .Net Framework so accessible! BibliographyPetzold, C.(2001). Programming Microsoft Windows with C#. Redmond :Microsoft Press. Chappell, D. (2002). Understanding .Net: A Tutorial and Analysis. Redmond :Microsoft Press. Richter, J.(2002). Applied Microsoft .NET Framework Programming. Redmond :Microsoft Press. Birdwell, R., Raybould, N., & Goode, C. (2002). Beginning ASP.Net 1.0: with VB.Net. Birmingham: Wrox. Chappell, D. (2002). Understanding .NET: A Tutorial and Analysis. Addison-Wesley. AppendicesAppendix A. Classic ASP Original Code Sample<% ' Create a connection to the database and open it accessdb=server.mappath("db\main.mdb") strconn="PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" & accessdb set conntemp=server.createobject("adodb.connection") conntemp.open(strconn) %> . . . <% set CatList=conntemp.execute("SELECT Category_ID, Category_Name, Category_Clicks FROM Category") %> </p> </div> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr width="150"> <td><div align="center"><span class="bodytext"><strong><font color="#000000">Select a product category from the list below...</font></strong></span><strong><br> <br> </strong></div></td> </tr> <% CatList.MoveFirst While NOT CatList.EOF %> <tr width="150"> <td height="15"><div align="left" class="bodytext"><a href="SubCatDisplay.asp?Category=<%=CatList("Category_ID")%>"><%=CatList("Category_Name")%></a></div></td> </tr> <% CatList.MoveNext Wend %> </table> Appendix B. Delphi .Net Code<%@ Page language="Delphi" %> <%@ Import Namespace="System.Data"%> <%@ Import Namespace="System.Data.Oledb" %> <%@ Import Namespace="System.Data.sqlClient" %> <script runat="server"> procedure Page_Load(Sender: System.Object; E: EventArgs); const sqlStr = 'SELECT Category_ID, Category_Name FROM Category'; var objConnection : OledbConnection; objCommand : OledbCommand; objDataReader : OledbDataReader; accessdb, strconn, strResultsHolder : String; begin accessdb := server.mappath('db\main.mdb'); strconn := 'PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=' + accessdb; try objConnection := OledbConnection.Create(strconn); objCommand := OledbCommand.Create(sqlStr, objConnection); objConnection.Open(); objDataReader := objCommand.ExecuteReader(CommandBehavior.CloseConnection); except on e : exception do testD7.innerHTML := 'Category exception ' + e.message; end; // try strResultsHolder := ''; if objDataReader <> nil then begin while (objDataReader.Read()) do begin strResultsHolder := strResultsHolder + '<a href="SubCatDisplay.aspx?Category=' + IntToStr(objDataReader.getInt32(0)) + '">' + objDataReader.getString(1) + '</a><br>'; end; // while if strResultsHolder > '' then Categories.innerHTML := strResultsHolder; end; // objDataReader <> nil if objDataReader <> nil then objDataReader.Close(); if objConnection <> nil then objConnection.Close(); . . . <div id = "Categories" runat="server"> </div> Appendix C.The Custom Control in the Default.aspx file<%@ Page Language="vb" CodeBehind="Default.aspx.vb" AutoEventWireup="false" Inherits="ShopNelson.CDefault" %> <%@ Register TagPrefix="ShopNelson" TagName="Menu" Src="_Menu.ascx" %> <HTML> . . . <p><ShopNelson:Menu id="Menu1" runat="server" /></p> The Control in the _Menu.ascx filePublic MustInherit Class C_Menu Inherits System.Web.UI.UserControl Protected WithEvents MyList As System.Web.UI.WebControls.DataList . . . Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim products As ShopNelson.ProductsDB = New ShopNelson.ProductsDB() MyList.DataSource = products.GetProductCategories() MyList.DataBind() End Sub The Relevant Code in the ProductsDB.vb File.Public Function GetProductCategories() As SqlDataReader ' Create Instance of Connection and Command Object Dim myConnection As SqlConnection = New SqlConnection(ConfigurationSettings.AppSettings("ConnectionString")) Dim myCommand As SqlCommand = New SqlCommand("ListCategories", myConnection) ' Mark the Command as a SPROC myCommand.CommandType = CommandType.StoredProcedure ' Execute the command myConnection.Open() Dim result As SqlDataReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection)
' Return the datareader result Return result End Function Bulletin of Applied Computing and Information Technology Vol 1, Issue 2 (December 2003). ISSN 1176-4120. Copyright © 2003, Ryan Clarke, Paul Ropper |
|
Copyright © 2003 NACCQ. All rights reserved. |