Saturday, June 18
by Dave Bernard
It was a dark and stormy night...
...that was the introduction to my first trip to Montreal. I had been looking forward to swapping hot and humid Atlanta weather for
the considerably milder clime to the north. Even with the precipitation, I was not disappointed.
I was also looking forward to dusting off my considerable (but distant) high school French; however, just like in high school, I can read it far better than I can understand it or speak it. Since
French is the official (and first) language of Quebec, you learn quickly to "prompt" the waiter, counter person, concierge, etc., with a "Hi" or "Hello" so that
they swap their French memory stick for their English one before responding.
We registered early Saturday morning, receiving a nice backpack with materials, including a really useful white paper by Kevin Kline of Quest Software, Finding and
Fixing Bad SQL in Microsoft SQL Server 2000. The first day of DevTeach 2005 consisted of an optional full day of pre-conference sessions. Carl Franklin, Jim Duffy and Rod Paddock anchored eight hours of an introduction to
VB.NET, OO with .NET and developing with SQL Server and .NET. Their sessions were well-attended and, by all accounts, it was a very worthwhile investment.
I ended up covering the other half of the day's offerings, two sessions by pre-conference newcomer Bill Vaughn of Beta V Corporation, though he's anything but a newcomer in the business. Bill's a prolific author, highly-regarded
speaker and regular magazine columnist. His experience spans over 30 years, starting with mainframe work, and closely parallels the growth of the PC software development
sector.
ADO.NET Coding and Best Practices Workshop
Bill Vaughn
by Dave Bernard
Bill started out by introducing himself and summarizing his extensive experience in the software development business, apparently spending much of it, however, driving companies into bankruptcy. It would be
interesting just to hear all his war stories after having gone through stints with EDS, Digital Research,
Microsoft and others. After his spot-on imitation of Ross Perot, Bill polled the audience about what they wanted out of the session, eliciting a wide range of responses from the attendees, whose diverse
backgrounds included C++/MFC, Oracle/Java and VFP folks moving to .NET. It all boiled down to a desire to get a solid understanding of the best way to manage the data access
layer while developing in Visual Studio .NET. We then went right to the material, which was a full-day course (based on his upcoming book Hitchhiker's Guide to Visual Studio and SQL Server 2005) that Bill had compressed to half that.
Bill is a detailed and knowledgable guy, so this fast-paced session was crammed to the gills with details, tips, examples and demos (his presentation included over 170 slides!) Bill included a lot of valuable background and
anecdotal information on the previous, current and future states of the VS .NET Beta. The ADO.NET functions were presented in the context of ADO Classic, ADO.NET and ADO.NET 2.0,
which was very helpful in understanding where on the data layer management path we currently stand, and where it's going.
ADO.NET is Microsoft's language-agnostic data access classes for the .NET Framework. It provides the data access pathway to specific data engines (SQL Server, Oracle) via
"native" protocols, either managed (SQL Server) or unmanaged (Oracle, OleDB via COM Interop).
A lot of what he demoed and presented was very new ("you're seeing things that few others in the world have seen"). Some of the more interesting ADO.NET 2.0 items:
- The new SQL Server Native Client provides support for the new SQL Server 2005 feature set, but is also designed to work with VB6 without requiring MDAC. This is one of the
many new Visual Studio changes that target the (apparent) legion of VB6 developers who feel disenfranchised by VB.NET. Microsoft has definitely heard their pleas/anger/concerns and is
working diligently to get these folks back on the bandwagon.
- Support for asynchronous operations, allowing an application thread to continue while the data thread is running.
- SQL Server notifications can be generated and transmitted to the application when certain pre-defined data events occur on the back end. These should be used with
caution, however, because they can get very "expensive" in a hurry.
- An application can now easily check for and react to server non-availability and broken connections. Also, connection pool cleanup is much improved and more robust.
- Bill's a big fan of the Fill method as a replacement for situations commonly attacked using DataReader. It goes a long way toward simplifying connection management and easing
the population of local record sets.
- Don't install the VS .NET 2005 Beta on your regular machine. Instead, use a clean machine with a fresh copy of the OS. Every time a new CTP comes out,
start from scratch. Don't try to uninstall a previous CTP; use Ghost or something similar to create a starting point and work from there.
- Add "ApplicationName=" to the connection string; this is a big help when trying to filter SQL Server Profiler output.
- A lot of new functionality comes from new methods that are essentially wrapped SQL-DMO and SQL-DML functions.
Some items in ADO.NET 2.0 seem incomplete. For example, Multiple Active Resultsets (MARS) is interesting, but very constrained and difficult to work with. And some things
seem to be missing altogether from ADO.NET, according to Bill:
- Server-side cursors;
- Asynchronous Open, Fill and Load;
- No way to manage Login Ids, User Ids, permissions;
- The DataAdapter Configuration Wizard is deprecated.
Bill made some good, down-to-earth points about performance vs. productivity. Don't spend inordinate amounts of time making the ADO interface work milliseconds quicker when
your back end stored procedure needs work. "Asking a question faster is not going to significantly change how long it takes for the recipient to create an answer." You have
to look at the full range of activity that occurs when you make an ADO request to a back end server and then move that data back to the application. Many best practices are
not the same for both desktop applications and web applications (connection persistence and management, for example). There are tradeoffs to consider; for example
the arguably less-readble Tables(0).Rows(0).Item(0) is at least three times faster than Tables("Titles").Rows(intN).Item("Title"). Use the new BulkCopy class to move
masses of records around on the back end; this is a very poor use of an ADO recordset.
Bill is a very quotable guy; "COM is evil" and "XML is great for communicating with space aliens" need no elaboration.
"I think Visual Basic .NET is not bad — it’s just different. In my opinion, it would have been far easier on everyone if they had just called it
something else — anything else. Visual Fred would have been better. That way developers
would know that it’s just another language."
William (Bill) Vaughn, President (Beta V Corporation) and Microsoft MVP, on the podium at VSLive 2001, San Francisco, February 2001
Bill informed us that Visual Fred was named after his daughter; it was her "soccer nickname" (his other daughter was "George"). "I raised them as people, not as girls" was Bill's
response to his incredulous audience.
Bill covered a lot of material;
I've just given you the veritable tip of the iceberg. If you get an opportunity to see Bill in action, don't pass it up!
SQL Server Stored Procedures, Today and Tomorrow
Bill Vaughn
by Dave Bernard
This session followed neatly after the ADO.NET session, with little overlap but a lot of relevance. The presentation was not quite as long as the first one (only 126
slides!), but was, again, very detailed and filled to the brim with nuggets large and small. One interesting tidbit Bill shared was that he is one of the co-inventors of
RDO technology, which occurred when he was at Microsoft.
Bill started out with an overview of the basics of SQL Server stored procedures, with special emphasis on parameter guidelines and the different kinds of inputs and outputs
supported. He also spent time summarizing some general rules of thumb regarding performance, permissions, error handling, event logging and how to use ADO.NET with
SQL Server.
With more functionality comes more decisions. You have to be aware of the type of output(rowsets, number of rows affected, scalar values, XML stream, etc.) you're expecting so that you can set the proper calling parameters in ADO.NET.
The stored procedure can also return error information to the calling application;
Bill went over the various ways that SQL Server reacts to the type and severity of the error it encountered. This can range from just returning a system or custom error
message string to terminating the offending statement to rolling back all changes to terminating the batch to terminating the connection. There are 24 severity levels that
govern this behavior; SQL Server 2005 will support TRY/CATCH exception handling to ease error handling. He went over how to use RAISERROR to create and fire your own
custom exception messages and optionally add them to the event log.
Bill spent a fair amount of time reviewing how SQL Server compiles and caches store procedures, and how execution plans are used to optimize store procedure performance.
You need to take care to understand how SQL Server manages dynamic database growth and how that can affect store procedure performance. For example, the tempdb database is used
for many behind-the-scenes activities when a stored procedure is executed; it is better to pre-allocate a larger tempdb database ahead of time than to allow potentially
unpredictable dynamic growth management to interfere with stored procedure performance. Bill summarized the situations that caused stored procedures to be recompiled, and noted
that, new to SQL Server 2005, query plans can be output to XML and accumulated so that they can be analyzed over time, enabling possible further optimizations. Ad-hoc queries
automatically take advantage of query plan caching and compilation, not unlike store procedures.
Since query plans are optimized across the entire store procedure, it is best to refactor large "all-purpose" stored procedures into a series of smaller store procedures called by a
mainline one. That way, each stored procedure gets it's own execution plan, which will be more efficiently optimized. The syscacheobjects table can be used to analyze query
plan reuse among stored procedure calls; use Performance Monitor counters to analyze performance characteristics.
Bill's last section covered understanding CLR stored procedures. First, he reviewed the basics of the CLR and IL technologies and how they fit into Visual Studio .NET and the
.NET Framework. New to SQL Server 2005 is the ability to code stored procedures, triggers, functions, user-defined data types, etc., in VB .NET, C# or MC++. While this sounds
very exciting and interesting, Bill urged caution; he felt and demonstrated that, at least initially, coding stored procedures in CLR languages can probably only be justified
for CPU-intensive tasks or as a replacement for situations that demand calls to COM DLL's from a store procedure. Bill walked through the creation of some simple and not-so-simple
examples of CLR-based stored procedures, including making sure to enable the capability (it is disabled by default) in the first place. You can also optionally deploy the code
in the database, so that it goes along for the ride when installing the database in a production environment.
Another aspect of CLR-based stored procedures is performance: T-SQL still significantly outperforms the equivalent CLR functionality, sometimes three- or four-fold. Of course,
your mileage may vary.
Thanks to Bill for a very enlightening and comprehensive session.
Sunday, June 19
by Dave Bernard
Things got off to an early start today with a great continental breakfast spread and long lines at registration. Looks like there will be quite a crowd in
attendance.
Developing Occasionally Connected CF Applications
Sam Gentile
by Dave Bernard
Sam's been doing .NET development from the earliest days, and is a C# MVP and INETA speaker. He's been working on a whole new paradigm for developing CF
applications that is not supported by the .NET Framework out of the box. Occasionally Connected Computing (OCC) is his core interest, and he opines that there is no such thing as always-on connectivity
Most of the audience were CF/mobile developers, but none had yet started with the CF .NET 2.0 Beta. Check out his blog.
Mobile and desktop apps target different types of users and tasks. Mobile apps tend to deliver with fewer, shorter duration tasks or features; session time
needs to be short, but data still needs to be persisted. Mobile devices need to function in tougher environments (noisy, single-handed operation,
disconnected, no power, unexpected failures); you need to assume no connectivity for long periods of time. What's driving this is the explosive growth in wireless capabilities, along with shrinking computing devices and expanding storage capacities. This is
leading to a radical shift from connected computing to OCC.
With the vast number of handheld devices in use at the "edge" of the infrastructure, there is a need to move data back and forth from centralized data
stores. Traditional client-server (and even .NET) architectures are inadequate to support this goal robustly, requiring a new approach where data and
applications are always available in spite of the connectivity situation. The primary challenge is to add the ability for the disparate parts of the
IT infrastructure to operate in distrubuted, synchronizable way.
Sam then presented a good summary of the Compact .NET Framework, and is a radically reduced subset (about 25%) of the full .NET Framework.
Microsoft designed it to deliver rich client capabilities in a cross-platform, low-memory environment, but there's a lot missing,
including COM Interop (a biggie), in which there is an existing large investment in the business world.
Sam then dived into the Whidbey. Whidbey innovates by integrating smart phone support, improved development and remote tools, much better deployment and debugging
functionality. Sam showed the new Design Time Environment (SDE) that brings much of the full framework IDE to CF development. He showed a neat way to
display your Pocket PC "desktop" on your development machine and even control it from there. Very cool stuff. Whidbey generally brings much more
compatibility with the full .NET Framework and remains side-by-side compatible with version 1.0. There are many performance improvments (unified JIT,
improved XML and string handling) and COM Interop support is much better (largely because of enhanced type marshalling). There are a lot of new
Windows Forms controls that bring a much richer UI toolset to the table.
Data access and SQL Mobile were covered next, which Sam feels to be the most important part of this. You need to figure out how your going to deal with
both local and remote data, especially in intermittently connected situations. The key is to always have a local full-blown relational database, which raises a whole
new class of issues, such as device memory impact and management and how to synchronize with the central data store. You could use XML (not a good idea) or
DataSets (very memory-intensive, not good for larger amounts of data, but SQL CE (SQL Mobile) seems to be the best approach (scalable, reliable,
supports transactions, feature-rich, small footprint, automatically deployed in Whidbey). Whidbey introduces SQL Mobile 2005 (SQL CE 3.0), which is
essentially SQL Server 2005 (Yukon) for a mobile device. In general, Sam thinks that SQL Mobile could be a very good solution for developers facing
problems with DataSets in mobile applications, especially in light of the new (and fast, fast, fast!) updatable, scrollable cursor.
Sam covered the basics of data synchronization, emphasizing, again, the need to work offline and be as loosely-coupled as possible. Remote Data Access and
Merge Replication approaches really require a persistent or near-persistent connection; the primary problem is determining which "deltas" (changes) to
send to the client (deletes, creates and updates).
Sam's session was valuable not just because of his explanation of the new CF-related features coming in Whidbey, but in encouraging developers to really
think about their overall approach to building data-centric mobile applications, that is, assuming only occaisional connectivity.
n-Tier in Practice - The TierAdapter Framework
Martin Salías
by Dave Bernard
Martin is a software architect and Microsoft MVP. He is also Editor-In-Chief of the Universal Thread Magazine and is a frequent speaker in Latin America.
The TierAdapter Framework is a lightweight n-tier application development framework based on Visual FoxPro 8.0 or higher that allows you to build rich, fast
and scalable database applications. It supports VFP, SQL Server and other ODBC/OleDB data sources. The current version requires VFP 9.0 and is being ported to .NET. It is released under the MIT Open Source
license and hosted at SourceForge (the very first VFP project there!)
Martin's goal in this session was to show how to use the TierAdapter Framework, so he went right into a sample application based on the Northwind
database (VFP or SQL Server versions). The sample application was a typical VFP desktop presentation (splash screen, login, menus, toolbars, entry forms,
reports, etc.)
One neat feature is the ease at which you can build a form that automatically pages a data result set, that is, fetch a page at a time (for larger result sets)
and display just a subset at a time. He also showed an interesting "combo" box that allowed searching by either a code or the name of a data element.
For example, you could search quickly by either a product code (if you knew it) or by a partial product name. The menu system in the framework is
table-driven and is connected to the robust built-in security model.
The overall architecture is based on the main abstract TierAdapter class. The DataTierAdapter, BusinessTierAdapter and UserTierAdapter classes are subclassed
from this main class. DataTierAdapter and BusinessTierAdapter classes are pretty self-explanatory; the UserTierAdapter deals with the UI part of the
application. Here's a good diagram that shows more detail. Of course, when building an
application, you want to first subclass the framework classes.
The ability to support multiple types of back ends (and switch between them) is efficient, easy and powerful. Back end connection strings are stored in
INI files; to swap to a different back end, simply use a different INI file. The core data functionality is based on the CursorAdapter and XMLAdapter classes
introduced in VFP 8.0.
Much of Martin's presentation covered specific code examples that underlined the ease of creating new desktop applications simply and quickly. It
supports complex UI cases, such as one-to-many forms. And it can be used with just about any deployment methodology out there (monolithic EXE, local DLL, COM+ DLL, etc.)
The TierAdapter Framework is a worthy candidate for those developers striving to build robust, feature-complete applications quickly and easily.
Windows Component Services (COM+) - Part 2
Craig Berntson
by Dave Bernard
Craig is a veteran VFP developer, author and speaker, few, if any, people know better how to take advantage of COM+ in VFP.
The Distributed Transaction Coordinator (DTC) allows cross-database changes to be wrapped in a single transaction. When performing these kind of operations
with COM+ DLL's, Component Services automatically calls the DTC, which in turn uses Resource Managers (RM) to talk to the database(s) involved in the
transaction. The problem lies in the fact that while COM+ ships with resource managers for SQL Server and Oracle, there is no such animal for VFP data.
Without a VFP RM, VFP data cannot take part in transactions under COM+. To make matters worse, RM's are very difficult to build.
All is not lost, however. COM+ supports an alternative to RM's: the Compensating Resource Manager (CRM), which are much easier to implement and can proide
the solution to our problem. Craig summarized the internal mechanism that defines the relationships between the COM+ DLL and the VFP CRM, which is really
a combination of a worker component (which maintains a recovery log and performs the main database action) and a compensator (which completes the transaction,
either committing it or aborting it). The application communicates with this mechanism via a business object DLL, which initiates the DTC interaction.
Microsoft delivers sample code to purportedly accomplish the entire mechanism, but Craig said it is deeply flawed, and that the samples themselves are
subject to one or more unresolved bug reports. They're located at C:\Program Files\Microsoft Visual FoxPro 9\Samples\Com+\CRM, but stay away from them!
Craig went into quite a bit of detail on the steps required to enable the CRM functionality under Component Services and how to install the VFP components
therein. Check out his session notes for the details and latest code examples.
Developing applications to work robustly in a distributed environment introduces special problems. In a distributed architecture, one component requests
data from and/or sends data to another component; it is never certain that either end of this relationship is always available. At the same time, it is
often important that, even if the receiver is not available, the requestor needs to keep functioning. Enter Queued Components (QC), which is an
easier way of working with Message Queues, and actually wraps MSMQ functionality in a familiar COM programming model to hide some of the original complexity of working with MSMQ.
Let's say you have a Client application taking orders. It needs to send an order to an Order processor, which in turn validates the order, adjusts
inventory perhaps, and then turns around and sends the order to a Shipping component. In this case, imagine that each of these three components reside
on separate servers, implemented as COM+ DLL's. We never want to stop taking orders, even if the Order processor is unavailable. And we don't want to stop
processing orders if the Shipping component is not available. QC allows the developer to insert a store-and-forward mechanism in between
each of the components, so that the working component can finish it's work, even though the component next in the chain is not available. The queue in
between gathers the transactions to be forwarded, and holds them until the target component is available, at which time the transaction is forwarded. QC is
transaction-aware, too, and works well across multiple stages, as in this example. Each component must be able to work in a mode in which it sends
transactions forward without expecting anything in return.
Another situation that Craig illustrated is (using the previous Client/Order/Ship scenario) when, say, all of the orders for a day occur in a short time
span (maybe a couple of hours) and puts a heavy load on the system. Trying to process this dense mass of Client requests in the Order and Ship components
may slow down the entire infrastructure to the point where order entry slows down unacceptably. In this case, the Order and Ship components could be shut
down while QC accumulates order requests during the busy time. After that, turn the components back on, and QC will automatically start forwarding the
queued orders to the Order component.
Thanks to Craig for once again tackling a very tough, important and interesting subject.
Putting the Task Pane Manager to Work
Tamar E. Granor, Ph.D.
by Dave Bernard
Tamar is a well-known consultant and mentor in the VFP community. She's a prolific author and writer, is a Microsoft MVP, lectures at the University of
Pennsylvania and serves as Technical Editor for FoxPro Adivsor magazine.
Tamar has shared many tips and techniques in the past that help VFP developers improve their efficiency and day-to-day organization.
The Task Pane Manager, introduced in VFP 8.0 and written entirely in FoxPro, is really a portal made up of a container that holds task panes (seven
of them in VFP 8, and eight in VFP 9). A task pane can be a good place to anchor your software development activities by organizing frequently used projects,
tools and resources. Individual task panes, and The Task Pane Manager itself, are highly configurable and are written completely in VFP and stored
in a VFP table.
You can easily add third party task panes (see some at Task Pane Central) or roll your own if you
like. Creating your own task pane is not simple, but it may be worth the investment if you can create one that will save you some time in your day-to-day
work.
Two of the most useful included task panes are the XML Web Services and the Data Explorer task panes. The XML Web Services pane greatly eases the discovery of
existing web services and can easily create code via drag-and-drop that you can paste into your program to give you a jump start on consuming a web
service. Once you've discovered and registered a web service through this task pane, you can quickly and interactively test real method calls to insure that
results are what you were expecting.
The Data Explorer is my persona favorite, since I work a lot with SQL Server. It is very nearly a clone of the most useful functionality found in SQL Server
Enterprise Manager, and allows me to do a lot of housekeeping and management for my SQL Server environment without ever leaving VFP. And that same familiar
functionality works for other ODBC/OleDB data sources. Drag-and-drop is enabled throughout, and can be used to quickly create running VFP code to handle a
particular data source. Very cool.
Environment manager pane is a good place to manage multiple projects and their respective working environments (default path, etc.) The environment
settings for each entry is powerful; you can hook code in before and after the project loads, for example. Field Mapping allows you to map a data type
(say, DateTime) to a form control (say, a calendar control) for drag and drop purposes. The only problem is that these settings are stored in the registry,
so multiple FoxPro instances using this capability could step on each other's settings. Once you've created an evironment set, you can associate one
or more projects with that set, so that when a project is loaded via the Environment Manager, all the settings get applied right then.
The Solution Samples pane is a portal to one of the most underused resource of all: over 100 code samples, all delivered with VFP and all nice and neatly
categorized. It's a wonder that this does not get more attention.
Task panes are distributed as XML files and are installed via the Task Options dialog. Everything's stored in Taskpane.dbf. You can also run code from a
pane; it supports a "namespace" called vfps:; so "vfps:modifyproject" will run a previously defined custom method call modifyproject.
Check out Tamar's (always helpful) session notes for detailed instructions and code samples. And take the "pane" out of your development chores!
Advanced COM Development
Martin Salías
by Dave Bernard
Martin is a software architect and Microsoft MVP. He is also Editor-In-Chief of the Universal Thread Magazine and frequent speaker in Latin America.
Martin has a thorough knowledge of the inner workings of the COM DLL model, especially with regard to using it with VFP. He started out by going over the
basics of creating a COM DLL in VFP and showed how to use the Error method to send exceptions back to the calling program via COMRETURNERROR. One
interesting item was a bit of code that he runs to build a DLL that takes care of unregistering the previously registered incarnation to reduce
registry bloat. A really good tip.
Martin briefly covered the threading models available to VFP COM DLL's. Compliling a multi-threaded DLL (actually Single Thread Apartment Model) is the recommended approach.
Free threading or Multi-Thread Apartment Model is not available in VFP. When a DLL is compiled, a type library is created, which describes the DLL's
methods, properties and other attributes. The VFP Object Browser is a good way to
explore the structure and features of a given DLL. The Type Library also drives Intellisense for that DLL.
It's a good idea to "protect" or hide those methods and properties that don't need to be accessed outside the DLL itself. These are often methods that can
only be called by other DLL methods and shouldn't be called alone. You can set this, and other method- and property-level attributes through the use of COMATTRIB. You
can set properties to be read-only, set a help string, etc.
Each DLL contains a vTable, which is a table of methods and of their entry point addresses.
Every COM component implements the IUnknown interface
and most implement the IDispatch interface; these establish a common call architecture for the DLL functions. There are two ways of binding in VFP.
Late binding refers to binding at runtime, while early binding is accomplished at design time. Early binding uses
the vTable to resolve relationships, while the IDispatch interface is use for late binding.
VFP's EventHandler allows you to fire a COM method based on events in an external class. You'll need to implement the full external class interface and
augment that with the code you want to fire when one or more of those external events fire. You can drag an interface from within the Object Browser to a code
window and VFP will generate the interface in code; very handy and a big time-saver. Martin demonstrated code that hooked the ADO RecordSet functions and
another that hooked the Microsoft Word object model. He also showed an example that hooked Microsoft Outlook and automatically added specific text to the
email body when the email was sent by the user. Interesting...
Martin has some good code examples and demos in his session notes. I encourage you to look them over and see what they can do for your projects!
What's New in System.XML V2
Christoph Schittko, Microsoft MVP XML
by Éric De Carufel
Christoph started off with the basics: What is XML? He then polled the audience about why they are using XML. Some of them are not using .NET at all.
System.XML V2 overcomes the following V1 issues:
- XSLT performance
- Schema validation performance
- Better standards compliance
- Inconsistent programming interface
- No type
- Lack of advanced query capability
The framework was released before the standard was fixed, causing widespread complaints. In V1 there were too many types available to read XML and
you never knew which one to use. Christoph then demonstrated many of the features of the new XMLReaderSetting type. The instance returned is a simple
XMLReader. The framework takes care of everything; it chooses the right implementation of the right reader based on attributes specified.
Validation in V2 is pretty much the same as it was in V1, but standards compliance is much improved, including the ability to validate via DTD.
In V1, it took about 15 lines of code to keep the document valid while modifying an XML. In V1 you only have to call a Validate method.
XPathNavigator in V1 was a good way to navigate an XML document, but it was readonly. In V2, it is read/write. There are many usability improvements,
like the ability to append elements straight from the navigator itself.
In V2 there is a new sgen command that compiles and deploys an XMLSerializer DLL, removing the overhead of doing it at runtime. It is now OK to
implement IXMLSerializer to serialize a type even via a Web Service.
In V1, XSLT was not as fast as in the COM implementation. The V2 implementation compiles itself straight into MSXML format, which is much faster.
There is now a new template available to edit an XSLT template. After a long time waiting for the editor to load, Christoph showed some of its new
features. There is an IntelliSense macro to render an HTML table using a simple XSLT transform. All you have to do is fill in the blank to get
your template done. It is also possible to debug the transformation while it processes the XML document. You can sets breakpoints in the XSLT.
Performance improvements:
- Microsoft .NET 2.0 implementation is twice as fast as Java 1.5.
- XML Schema validation is 20% faster.
- XMLTextReader is 100% faster.
- XMLTextWriter is 100% faster.
- XSKT is four times faster.
MSBuild: Release Engineering for .NET 2.0/Longhorn
Nickolas Landry
by Éric De Carufel
The base principle of release engineering is "never build the final release on the developer machine". You should automate the process on a build
lab where all component versions are closely monitored. This is part of the key concept of Continuous integration, itself at part of the
Test-Code-Refactor approach, in which a test is written for every bit of code before you code it. It takes a lot of discipline but you ensure better quality.
Refactoring is essential to the success of this process. It makes code better and easier to read and maintain. When you refactor, no functionality
should change, only code structure. Reafactoring means your code will change a lot, so you must have a good, reliable testing process in place.
In Visual Studio 2005/.NET 2.0, MSBuild is used to handle the build process. You do not have to install a licence of Visual Studio on the build
machine. It takes the project file as a build script. MSBuild itself was actually used to build Longhorn (the OS itself!)
Nick took some time to present an overview of a VB Project file. This file is the file that will be used by MS Build to build that project.
The Visual Studio IDE will ask to reload the file if it is modified outside its own property editor. MSBuild accepts command line arguments that
specify a particular build configuration (debug, release). MS Build is also compatible with Visual Studio solution file. The project file can also be
modified to include tasks other than compilation.
A custom task usable by MSBuild must implement ITask or derive from Task, and must include references to the Microsoft.MsBuild.Framework and Microsoft.MsBuild.Utilities
namespaces. It must also implement an Execute method.
ASP.NET Data Caching Magic
Carl Franklins
by Éric De Carufel
http://www.theday.com uses ASP.NET caching for all their web site content, refreshing it every day at
6:00 am.
Carl is not a PowerPoint guy. He starts his session straight off with Visual Studio. After setting up a page with a datagrid in it and applying some
basic styles, he put some code in the code behind file. To demonstrate how caching works, he created a simple dataset and filled it with data from
the Author table of the Northwind database. He then added some code to check to see if the dataset is in the cache and, if not, the code will load it into
the cache. Keep in mind that the cache object has the same scope as the application itself, which means it is shared across all sessions.
There are two ways to do cache expiration: Absolute and sliding. Absolute Expiration sets the expiration at a fixed moment in the future. This
moment can be calculated. For sliding expiration you must specified a time span duration in which the cache will expire.
A cache dependency is an object waiting for a specific event to occur. The simplest cache dependency object is CacheDependency. The constructor
takes a filename as it single argument; as soon as there’s a change in that file the cache immediately expires. In Visual Studio 2003, there is no
database dependency. As Carl said, it’s a good motivation to upgrade to Visual Studio 2005. He shows how to make it work in 2003 by creating a
trigger on a particular table that touches a file on disk from which a CacheDependency depends. An event is fired when a cache expires,
but to make it work you must create a singleton class in order to keep a reference to it, otherwise it will be lost and the callback would have no object.
Carl demonstrated how to always get live data as well as using cache for performance. The idea is that whenever the cache expires, the callback
immediately refreshes it so that the next page refresh will get live cached data.
Carl recommends to always subclass the page class and derives all your pages from it. In a page class there’s two overrideable methods that
are called in turn when a page instantiates. SavePageStatePersistenceMedium and LoadPageStateFromPersistenceMedium are called to get data to
and from the Viewstate object. This is a good place to hijack the overgrowing Viewstate and put it in the Session object. This way, it creates
a much smaller rendered page to the client browser. The trick is to persist this Viewstate into a state server by using System.Web.Ui.LosFormatter.
See Carl's demo.
Security Through Least Privilege
Don Kiely
by Éric De Carufel
Security is not a new concern of programmers, but today, with all these computers connected, it become much more difficult to develop secure applications.
By default, you always run as a local administrator. That’s the problem! In this scenario, you are more open to attack: if a process runs
under your account, it has unlimited access to your machine. Also, you cannot write secure code. Because you have all privileges you cannot test
a scenario when your application will run under least privilege. So you can develop functionality that will not run in the production environment
and this will become a bug.
You should only login as an administrator when necessary, such as when you modify things that should be applied to all users or when you modify
some core setting of the operating system.
The solution is the Least Privilege User Account (LUA): only grant to the user the privileges the user needs and no more.
Why we do not want to be a mere user:
- I’d rather fight than switch!
- It’s too hard!
- Makes everyday computing inefficient!
- You need admin privileges to write software!
- Lots of stuff breaks
- Great way to learn about what happens to real users
- And therefore a great way to learn how to develop secure software
Don explained all the problems related to running as a LUA:
- You won’t be able to run some applications
- Watch Windows event logs for a few days; there will be some things you need to attend to
- Some apps will break randomly (seemingly)
- You’ll not be able to read app data (rare) or write it to where you have been (common)
- You can’t be blamed when protected resources are messed up
- You can’t run Windows Update
- Some effects will be lessened if you convert rather than start fresh with Windows rebuild
Some problem for developers:
- Can’t disable wireless network connection
- Can’t change system time
- Can’t admin IIS
- Can’t kill processes
- Access error #5: Access denied
Power Users is not a good choice because it is only slightly more secure than Administrator. User is a better choice but it has some problems.
To be secure, it’s a good practice to rename the administrator account and remove its description. If the Secondary Logon service is running,
you can choose RunAs from the context menu when you start an application from its shortcut.
Monday, June 20
by Dave Bernard
Data Access in .NET for VFP Developers
Les Pinter
by Dave Bernard
Les began his programming career with FoxPro while employed by LucasFilm, and is the guy who sold a 23-year-old named Bill Gates the foundation for the first version of Microsoft Word for about $30,000. Everytime he looks up and
sees a Learjet going by overhead, he thinks "I could have had that!"
Visual FoxPro made data access incredibly easy because of certain constraints it placed on usage. The designers of VFP assumed data connection persistency, which greatly simplified their implementation and allowed the inclusion of a very powerful feature set.
Data access in .NET is disconnected, which makes robust data access support a much, much bigger challenge. VFP developers are used to VFP doing a lot of implicit work
in the background (automatic posting of updates, easily populating a browse, etc.), while .NET requires a lot more granular interaction by the developer to
accomplish the same tasks. In addition, you've also got to learn how .NET itself works (constructors, overloading, references, etc.); it can take
months to get a handle on it.
When working with SQL Server, VFP developers have to be aware of significant differences between working with VFP data and SQL Server data:
- VFP has 18 data types, SQL Server 25, and the mapping is not quite 1:1;
- SQL Server dates are DateTime, a hassle;
- You can only delimit strings with single quotes;
- Many more reserved words in SQL Server;
- Moving a database from one machine to another is tedious.
Les started with some background regarding SQL Server, which is commonly used as the data back end for .NET applications.
Using stored procedures is highly recommended with SQL Server, and UDF's are supported in SQL Server as in VFP. When working in .NET, you need to make
sure that two libraries (System.Data and System.XML) are included, which is done automatically for a Windows project, but not for a DLL project.
Filling a DataSet, the standard .NET local data structure, is much like connecting to SQL Server in VFP: establish a connection, pass a query or command in a string
and receive the result set. In .NET, you must also first instantiate a dataset, then use the Fill method to populate the structure. The Fill method is
largely preferred over the use of DataReader, as was common in the past among .NET developers. Connection String is a great resource for creating connection strings for various back ends.
Les started up VS .NET and built a quick data-aware VB.NET windows form to demonstrate, just in general, how developing this kind of application would to look
to a VFP developer, drawing parallels between .NET form handling and the VFP event model. Data binding starts with dragging an OleDBAdapter to the form,
then use the Data Adapter Configuration Wizard to finish the work. Unfortunately, this wizard disappears in .NET 2005, which is unfortunate, because it
looks like it would save developers a lot of time.
Overall, Les feels that .NET data handling is a lot slower than what you'd get performing the equivalent operation in VFP, so be careful what you promise your customers regarding
performance, especially if they're migrating from VFP to .NET. .NET generates a lot of code for each dataset you need to use in your application. It
seems that much of the work that .NET is performing is, in fact, overhead necessary to transform a data structure into a class-based object.
As an aside, there is definitely a push on within the Microsoft .NET team to bring much of the powerful features and ease of data access that VFP
developers have enjoyed for years. One of the reasons VFP did not become VFP.NET was due to the fact that the .NET Framework did not have the ability
to support those rich VFP data access features. VFP has already donated Rushmore technology to SQL Server and data access functionality to ADO.NET. Stay tuned...
Les went into great detail, in code, to show how data binding is implemented in a typical .NET windows form. Even
if you grasp the data object model used in .NET, some conventions seem counterintuitive. For example, you would expect to be able to do something like
DataSet.Skip to move to the next record. In fact, you have to use something completely different (BindingContext) to accomplish it. Huh? You'll
find the equivalent of VFP's TABLEUPDATE within BindingContext, too, when DataSet.TableUpdate would seem a more natural way.
Les spent some time summarizing the .NET equivalent of various VFP commands. Much of the basic data access functionality an application needs is
contained in the aforementioned BindingContext class.
So much of what we do as developers on a day-to-day basis is done subconsciously. We perfect habits and thought patterns that allow us to work as
efficiently as possible in the toolset and paradigm in which we are developing applications. The .NET Framework, to a VFP developer, will require you to
substantially change a lot of your daily habits. This aspect of moving to .NET is rarely brought up because it is difficult to measure and varies by degree from
person to person, but ignore it at your own risk.
Many thanks to Les for a very good job providing an introduction to .NET development that speaks to VFP developers.
Putting Your VFP App on the Web
David Stevenson
by Dave Bernard
David is an MCSD, editor of FoxTalk 2.0 and a long-time FoxPro developer.
Increasingly, VFP developers are being asked to "webify" existing business applications. The reasons vary, but most often it's a company that
is expanding and needs to centralize their data to make it available, not only to current users, but also to non-traditional users (customers and vendors).
Rewriting applications from scratch is very risky a rarely cost effective, especially with long-running mission critical applications. Your current
architecture (FPDOS, VFP, modularity, client-server) has a lot of bearing on where to go and how. You also have to decide upon where you want to end up;
will it be a complete web application, a fat client application hitting web-based data, do you want to expose all or part of the new system to other
systems (.NET, etc.)?
There are alternatives to converting. For example, use an application-sharing technology (Citrix, Terminal Services) to simply share the original application
over the web to multiple users. However, there are significant potential problems (screen painting issues, memory management, scalability).
Building a distributed n-tier web application means working in a non-persistent, disconnected way. There's no constant "state" to lean on.
You have to re-establish the context for each operation you attempt. The concept of "next" is not useful without a specific starting point.
State can be maintained several ways (cookie, URL "license-plating", hidden form variables, server-side data table).
David showed a couple of good examples where substantial FoxPro code was salvaged to be used in a web application. One was an ancient non-FRX-based report
that was useful on the web after just a few changes. The other was a large, complex piece of business rule calculation logic that was used virtually
unchanged. David also discussed what it takes to build a responsive UI and how to handle security concerns.
It is a challenge to go from building pure-VFP applications to building COM-based web-enabled applications that use VFP in the middle tier. The developers
toolbox expands considerably to include HTML, Javascript, Cascading Style Sheets (CSS) and VBScript. These are all essentially new languages with their
own syntax idiosynchracies (ENDIF <> End If) best practices. There is overlap in these tools regarding functionality and how to use a particular
technology in a particular way in your application. In addition, the VFP developer will be exposed to some new management tools (Component Services, IIS).
"How much of the old code can you take with you..."
....NOT MUCH!!
You've got to let go of your code; in a pure web application, none of your VFP UI will be reusable, so throw that out, along with any kind of navigational
constructs (menus, toolbars). What's left is a candidate for reuse.
David spent some time detailing the trail of activity that ensues in a web-based round trip. He then underscored that information with code he has used
in conjuction with West Wind Web Connection, a VFP-based tool for building web-based applications, and one of several ways to accomplish this with off-the-shelf
tools (others are Active VFP, FoxWeb, Active FoxPro Pages). In addition, you can roll your own VFP-based web framework (the path chosen by yours truly), if
you are so inclined. VFP comes with some web samples in the FFC HTML classes; look for GenHTML.prg, too.
Be sure to download David session notes. Also, David's
Tamar is a well-known consultant and mentor in the VFP community. She's a prolific author and writer, is a Microsoft MVP, lectures at the University of
Pennsylvania and serves as Technical Editor for FoxPro Adivsor magazine.
Visual FoxPro 9 improves SQL support by leaps and bounds, due primarily to improved compliance with the ANSI 92 SQL standard.
Many operations that previously required multiple SQL calls can be combined into a single SQL call, and many of the limits imposed in VFP 8.0 have been removed.
For example, VFP 8 had limits on the number of joins, subqueries (and subquery nesting), UNIONs and tables that could take part in a SQL call. All of these
constraints have been removed in VFP 9.
Tamar went right into examples and demos, certainly the most effective way of showcasing the new SQL capabilities. She had a customized version of a
contacts table derived from the Northwind database that comes with VFP.
A heavily normalized data schema is difficult to query optimally if there's a limit on the number of JOIN conditions. Tamar showed a very complex query
with 16 joins that takes a complex schema and returns one record per person, aggregating their various voice, personal, address, etc., information into a memo field
on the record. In VFP 8, this would take a lot of queries and connecting code. In VFP 9, one (large) statement. One other advantage is that you'd now be
able to incorporate that single statement into a view, which would have been nigh impossible in VFP 8.
A derived table is a powerful concept that SQL Server developers have long relied upon. Subqueries could only appear in a WHERE clause in VFP 8; in VFP 9,
as derived tables, they can exist in FROM clauses, columns, UPDATE correlations. They cannot be correlated, though.
Another very useful capability new to VFP 9 is the correlated UPDATE. You can list multiple tables, specify how they relate to each other, and draw the
replacement data from those other tables. You can perform similar operations with DELETE. Very cool.
Some performance improvements will bring a smile to your face. For, LIKE with % is fully optimizable and TOP n speed is better.
Another feature new to VFP 9 is the ability to force the query to run against buffered data, not what's on the disk.
If you are a VFP developer who also works heavily with SQL Server, these changes will change your life. Up until now, you had to keep two separate sets
of rules and constraints regarding constructing SQL queries in your head. VFP 9's SQL improvements reduce the differences between it and SQL Server enormously.
Tamar's session notes contain a wealth of real world code examples; this is a must for anyone serious about getting the most out of VFP's SQL capabilities.
In the last few years, the North American IT industry lost over 1 million jobs, including, in the US, 16% of the software development community. If you're a FoxPro developer, you've probably felt the heat. One way to hedge
your career bets is to diversify your skill set. To do that, you've got to start by diversifying your toolbox. Given the popularity of the .NET Framework and the
growth in the use of .NET languages, it can make sense to begin to head in that direction. Les recommends VB.NET for VFP developers looking to expand their
horizons, mainly because it will seem more familiar to them than C#.
Les jumped right in and started from the beginning: building a project. He iteratively built the test application as he explained the various features and capabilities
of Visual Studio and VB.NET, mixing his .NET commentary with relevant VFP comparisons. The IDE automatically adds the required .NET libraries (known as
namespaced) based on the type of project (EXE, DLL, etc.) chosen. Usually the commands and functions you need are methods of a .NET NameSpace, so, in
order to use a function, you must include a reference to its namespace.
Developers who have long suffered the weak and long-lived menu designer delivered with VFP will probably fall in love with the Visual Studio menu
designer.
VFP developers have long gotten away with loose typing of variables in their applications. The default setting for this behavior in VB.NET is the opposite:
all variables must be declared before using it. This is an excellent habit to get into, and good form (so the purists say), but I think it's value is
overrated, especially for experienced developers. If you're new to software development, do it.
The room is full; the most popular session I’ve attended so far.
Design Patterns describe concepts or processes on an abstract level. When we talk about a pattern, we don’t have to explain in detail what we want
to explain. We are all using patterns in every task as developer, it's just a common way of doing something. When you open a connection to a database
or when you take input from a web page, you are using a pattern. There are patterns everywhere. Every new technology has its own problem to solve, so patterns are constantly emerging.
A Factory Pattern provides an interface for creating families of related or dependent objects. This pattern relies on a class (the factory) to create
an object. The developer doesn’t have to know how to instantiate the class. A basic factory implements a GetObject.
A Singleton Pattern ensures that a class has only one instance, and provide a global point of access to it. A singleton pattern is a good pattern to
use with the factory pattern because you don’t want to have more than one instance of a factory. To implement a singleton you must use a static field
to hold the single reference of that class instance. Most importantly, the constructor must be private. So it is not possible to create an instance
outside the class. To do it you must call a public method that will return a static private field which holds a reference to an instance of the class
itself.
A Façade Pattern provides a unified interface to a second set of interfaces in a subsystem. Behind the scenes, a façade can instantiate many other
classes to accomplish its task. To the developer, it can be as simple as a single method call.
The Proxy Pattern is similar to the decorator but serves a different purpose. From a developer point of view, it looks like the real object when the
decorator is another object. This pattern can also be called a wrapper.
A Hook Pattern defines an extensible class or method that can call additional code through composition, and is often used in conjunction with events.
The Iterator Pattern provides a way to access elements of an aggregate object sequentially without exposing its underlying representation.
Internally, an Iterator keeps a pointer to the current item. It has a method to skip to the next object and another one to set the pointer to the
first object of the list.
The Mediator Pattern defines an object that encapsulate an object, promoting loose coupling by defining how objects talk to each other. A mediator
object is used to encapsulate a task that can be executed over many different types of objects and is accomplished through an interface.
An Observer Pattern defines a dependency between objects so that when one object changes state, dependent objects can be updated. There are two types
of observer: passive and active. A passive observer registers as a publisher and waits for an event to occur. When that event occurs, the publisher
raises an event method that initiates a call to all observer registrants. An active observer continuously checks to see if it has something to do
and to act when there is.
The Strategy Pattern provides interchangeable behavior. The base concept is to set an interface that all classes will have to implement. Each
individual class can derive from any other class, but as long as they implement the set interface they can be used in the same context.
The main benefit of using CodeDOM is to generate reliable and reusable code. That mean you have to debug it only once. After that you can reuse your
generator to create any number of outputs based on different inputs.
To start, you have to create a compile unit. From there you have to add every piece of structure of a standard source code set. You add your namespace,
imports, classes, fields, properties and methods. Then you add the CodeTypeGeneration to the compile unit and compile it. From now on you can run
it directly in your generator or you can create it as an assembly to use it in another project.
Dan's demo used SQLDMO to retrieve the structure of a database in order to extract a table list and table structures to fill a WinForm application.
This application uses CodeDOM to generate a business object based on selected tables and fields. The code generator is clever enough to get the right
CLR type out of a SQL data type.
Validation Groups apply only to the current group of control. You have to set a group name for each validator. Then you set which group each button
validates.
The Wizard Control is a server control that can be used to easily create a wizard. This is really just an encapsulation of overlapping panels.
Many attributes are available to control the flow of the wizard process.
URL Mapping is used to automatically redirect to another page. This feature can be really useful to redirect your entire site when you are performing
some maintenance.
There are now new server control attributes to add client script. The new SetFocus method of the Page object now allows you to automatically set
focus on a control of the page. This was previously done by registering some custom script. The page class has also a new property called DefaultButton.
This default button will be clicked if an enter key is pressed while the focus is on any fields of the form. There is also an OnClientClick attribute
that will render an onclick on that control. The ClientScript property of the page now gives access to all the client script features of the page.
TreeView Control: Finally, Microsoft provides a very flexible tree view control that is eaily bound to data.
MultiView Control: This is basically a container control; it's like a panel, except all show and hide features are built in.
BulletList Control: This just a label represented as a bullet list.
FilUpload Control: There is now a file upload server control.
HiddenField Control: This is another HTML control that is now available as a server control.
ImageMap Control: This new control encapsulates in a server control all the functionality of a client side image map.
Panel Control: This is not a new control, but it now has a scrollbar attribute.
This assumption that the network is reliable came from the way we have traditionally developed applications. On a developer machine, it’s very hard
to imagine that the network could be unavailable. In real life there are thousands of ways a network could fail; power failure, unplugged cable,
bad router. Software can also cause a network failure. And with the growth of wireless networks, it became more likely that a connection can be lost.
Latency is zero: we forget that, even if it is fast, it is not instantaneous. With current service oriented architectures, data may have many layers
to pass through from sender to receiver.
Bandwidth is infinite: even the fastest network infrastructure will reach its limit if you abuse it enough. The more bandwidth we have the more we use it.
The solution: don’t send more data than needed. Today's web sites send far too much data, much of it just to make the site look good.
The network is secure: developers do not necessary have deep knowledge of security issues. There are many points where data can be intercepted
and tampered by malicious software: desktop, servers, router, backbone network. Worse, a network can be hijacked to reroute network traffic to
another destination and make you believe you’re still connected to your server. Many web applications make it very easy for an end-user to do SQL injection
attacks. Never trust use input.
It is obvious that the network can, and will, change. Companies make structure changes, ether by choice or by need. Acquisitions can easily force
network changes. Perhaps a catastrophe forces a company to relocates a data center. These problems can be solved by layers of indirection,
like domain name sever (DNS) that enables you to change a server's physical address without changing the name by which it is known.
System Administrators get hired, leave or get fired and, sometimes, even go on vacation. You have to build systems that are easy to manage.
So it shouldn’t be hard to find or train another administrator that can do the job.
More and more different types of networks, from Novell and Unix to Web Services, that interact with each other. A system should not be built
to run on only one platform.
A system rapidly becomes unmanageable when it grows to a certain limit. It’s also impossible to change only a part of a system without rewriting
the whole system.
A system is finished only when the system is shutdown and never use again.