Data Access for Partially Connected Applications : Page 7
Modern applications require more sophisticated data access features than a simple connection to SQL Server. Data needs to be available in distributed scenarios as well as offline scenarios. This article provides an architectural overview and implementation examples that support these scenarios.
by Markus Egger
Feb 3, 2006
Page 7 of 7
At this point, you have a system with a lot of depth in its features. However, you still have a very narrow scope, since all the data services only support three methods. You could argue that these three methods support a very wide range of data operations, but I would expect these services to be more feature-rich. Here are some ideas of what you might add to your data services:
Add transaction support to the IDataService interface (and all implementations thereof) through methods such as BeginTransaction() and CommitTransaction().
Add code that attempts to detect SQL injection attacks by looking for comparison operators in the command text and see if they all use the parameters collection, rather than parameter values stored in the command string. The current architecture already provides some protection against SQL injection by supporting parameters, but this feature forces people to take the safe route.
Add security features such as application role support.
Add support for data readers. Data readers allow very fast and resource-friendly reading of data. The difficulty in the above scenario is that readers do not support the distributed scenarios as well as DataSets do. However, it can still be done with specialized reader handling in distributed environments. Performance will suffer a lot in those cases, but on the LAN, readers provide great performance, and over the Internet, users should not expect the same performance anyway, right?
Add methods that can load data asynchronously in a thread-safe fashion.
Add concurrency checking to the data service and raise events whenever concurrency problems occur, so developers can write interfaces that react to those events.
These are very technical features, but you may also be interested in adding more task-oriented features. Here are some ideas for those:
Create methods that can create command objects that perform CRUD operations (insert, update, delete) for updated rows in data tables. The command builder object can perform this task too, but you can provide more sophisticated or more specialized functionality.
Create methods that can create command objects for standard operations, such as retrieving a row based on the key value, retrieving a list of records based on foreign key values or the value of any given single field.
If you can abstract many of the standard data access operations in this fashion and put the burden on each data service object rather than your business logic, you can write very generic data access code that works in an optimized fashion on any given data source. Depending on your application, these methods can handle a very large percentage of data access operations, making it much easier to build applications that support various database technologies.
Even more polish could be added on the business object level. Currently, any code using this infrastructure needs to instantiate a data service. In a business object, you can add one more layer of abstraction by adding a protected ExecuteQuery() method to your base business object class, which is then available on all concrete business objects. This method is a direct map to the data service's ExecuteQuery() method, except that it also takes care of instantiating the data service, taking that burden off developers. The same can be done with all other methods exposed by the data service.
The architecture you created in this article is really just the beginning....
As you can see, the architecture and implementations you have created are really just the beginning. They form a base on which you can build your own architecture. As you can imagine, production implementations are likely to be much more sophisticated than the examples shown here, but the core concepts remain identical.
Markus Egger is president of EPS Software Corporation, located in Houston, Texas. He is also the founder of EPS Software Austria, located in Salzburg. He concentrates on consulting in COM-based, object-oriented development and Internet applications. He is an international author and speaker, and is co-publisher of Component Developer Magazine. He is also the author of "Advanced Object-Oriented Programming with Visual FoxPro," from Hentzenwerke Publishing. For the past several years, Markus has received the Microsoft MVP award. Several applications he has worked on (mostly as project manager) have received Microsoft Excellence Award nominations. He is the author of several tools, such as GenRepoX (public domain), the Fox Extension Classes, and Visual WebBuilder.