Browse DevX
Sign up for e-mail newsletters from DevX


Design Resilient Business Objects with MS DAAB : Page 2

Decrease the level of coupling in the Microsoft Data Access Application Block code by enabling it to use the MySQL database engine. With this technique, you can create highly resilient middle-tier objects.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Separation of Concerns
In practice, Separation of Concerns really just means congregating all code that pertains to a given task or task domain in the same place. A classic example is the task domain of database access. Consider this all-too-familiar scenario: One of my first tasks at a new job was to search through every single line of the company's Java code for mishandled database connections. The company's servers had to be rebooted every 48 hours or so when they ran out of connections.

Warning Signs in SQL Code
SQL statements defined "inline" in source code are a warning sign that the implementation or the project design itself probably includes some land mines.

If you see something like:

String sql = "SELECT CustomerID, LastName FROM Customers";

...you're most likely seeing code that is difficult to update or extend.

Had the developers centralized database access code in a single location, the code review would have been trivial. Instead, because they knew what data they needed for their class du jour, they just indiscriminately wrote code to go get it. In almost every case, this process included the following:
  1. Opening and closing the connection
  2. Creating queries with inline SQL
  3. Managing the returned database objects

The first two steps are downright tragic, and avoiding the last step completely could have created a considerable time benefit.

To demonstrate the benefits of Separation of Concerns and Loose Coupling in DAAB, this article examines a fairly typical middle-tier business object called "Product" (see Listing 1). Although greatly simplified for brevity, it nevertheless clearly illustrates the advantages of both the original DAAB code as well as improvements you can make to it. By virtue of factoring out database access to an isolated data access layer (SqlHelper.cs) , the Product class is clean, simple, and quite resilient in the face of change.

As simple as it is, the Product class nevertheless has a couple of interesting attributes. First, its simplicity is partly due to the fact that it has no database-access code at all. Normal database CRUD operations (create, update, and delete) are reduced to simple calls to SqlHelper methods. Since SqlHelper is a static method library, you don't even need an instance of the class to use it.

Second, the Product class is extremely resilient. Changes to the database-access layer will not require any changes to the Product class. This was accomplished by doing the following:

  • Using the SqlHelper.SetSqlParameter method to create database command parameters. This method returns a database provider-independent reference to the parameter interface, IDbDataParameter. No matter what specific parameter is being created on the other end, your business object dutifully passes it back to SqlHelper when needed.
  • Providing a delegate method that is passed an IDataReader reference (in this case, the GetInstance and ProcessReader methods). IDataReader is the interface that both MySqlDataReader and SqlDataReader must implement.

    The delegate method, ProcessReader, contains only the logic that must be in the Product class definition. That logic includes the columns that must be read using the IDataReader reference. This is really the only thing that SqlHelper cannot do on its own. Nevertheless, using an IDataReader reference instead of SqlDataReader greatly reduces the level of coupling. This small feature allows the Product class to be used by virtually any .NET-compatible data provider instead of just SQL Server (See Sidebar 1: Why Even True-blue Microsoft Shops Should Care About Loose Coupling).

The Product class code should raise a couple questions, including, "Where's the base class, BusinessBase, and why does Product need it?" Listing 2 shows the code for BusinessBase.

Although BusinessBase applies some business logic regarding the care and feeding of connection strings, why would you want every business object instance to maintain its own connection string? The simple answer is Loose Coupling. If business objects pick up their database connection information from keys in config files (a most common practice), then their implementations are tightly coupled to the database connection pools that the config file keys indicate.

This is usually not a problem, but in large, robust systems several database connection pools are often in use at once, each pool having different attributes—and maybe even pointing to different servers. It would be efficient if any given instance of your Product class could be used for any connection pool. Making the connection string a property of the base class enables that.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date