ADO.NET in Context

for RuBoard

Obviously, ADO.NET will be used primarily in the data services tier. However, in the context of an entire multi-tier application, you can think of where you'll write ADO.NET code from both the external and internal view with respect to the data services tier. Choosing an approach to take from each of these two views will lead you well on your path to designing the data services tier of a multi- tier application.

The External View

In the external view, you can think of the data services tier as a black box that exposes methods to which you make requests and from which results are returned. As mentioned previously, the code making the requests may be located in either the presentation or business services tiers, as shown in Figure 15.3.

Figure 15.3. External view of data services. This diagram depicts how code external to the data services tier will interact with it.

graphics/15fig03.gif

From the external view, the factor that determines whether ADO.NET components are used directly is the mechanism used to return the data. As you see from Figure 15.3, there are three basic approaches that the data services can take.

  • Exposing DataSet Objects . The data services tier may expose all its data in one or more DataSet objects. These objects have the benefit of being able to be automatically serialized for transport between tiers, and can be strongly typed to expose specific properties to represent the data. Using this approach, the external code will use ADO.NET to instantiate DataSet objects and work with its associated DataTable , DataRow , and DataColumn objects. The external code will then pass the modified DataSet to a method in the data services tier to perform the update. This approach has the benefit of allowing data binding in all .NET applications and built-in means of performing disconnected updates using the data adapter.

  • Exposing Data Readers . For performance reasons and perhaps because the application uses mostly read-only data, the data services tier may expose all its data through data readers. If this is the case, the tiers will likely reside on the same machine. Using this approach, the external code will use ADO.NET to capture a data reader and traverse it using its Read method, whereas updates will be performed by invoking methods in the data services tier and passing data as parameters. In this situation, the external code should also strive to use only the IDataReader interface to avoid being tied down to using a particular .NET Data Provider.

  • Exposing Custom Objects . Using this approach, the data services tier will return data through custom objects that expose properties and fields that contain the data. From the external point of view, no ADO.NET code will be required, so the System.Data namespace needn't even be referenced in the project. This approach has the benefit of allowing the other tiers to work with the data naturally through objects. The downside is that it requires more work on the part of the data services tier to populate and synchronize the objects.

In all three approaches just cited, the external code should strive to be loosely coupled from the data services. For example, the external code should never have to instantiate or work with command, parameter, connection, local transaction, command builder, or exception objects that are particular to a data provider. The data services tier should completely abstract these concepts and should simply expose the data itself as directly as possible. It's the responsibility of the data services tier to work with the provider, not the external code. For example, the data services tier shouldn't contain methods that return connection objects or expect command objects to be passed to them in parameters. In other words, the external code should work only with DataSet or data reader objects and no others from the System.Data namespace.

Note

Of course, the data services may also expose methods that return simple data types such as System.Int32 , System.Boolean , or System.String . This might be the case, for example, for a GetRevenue method that simply returns the total amount of revenue generated for a particular book over a certain time period.


The Internal View

From the view inside the data services tier, ADO.NET and all its features will be leveraged wherever possible. However, once again, there are three options for how you design your data services tier, as depicted in Figure 15.4.

Figure 15.4. Data services tier design. This diagram depicts the various approaches to the internal design of the data services tier.

graphics/15fig04.gif

Generally, these three approaches address the use of .NET Data Providers in the data services tier. The approaches are as follows :

  • Direct Approach . Thus far in this book you've seen examples of using a direct approach to work with the various providers we've discussed. By direct approach, I mean instantiating the concrete provider-specific SqlConnection , SqlCommand , and SqlDataAdapter and other classes directly in your code and using them. Within the data services tier, this means, for example, exposing a GetTitles method that uses the SqlDataAdapter directly to fill a DataSet object and return it to the presentation or business tier. This is the fastest approach in terms of development time and performance, although it requires code to be rewritten in the event the provider must be changed in the future. It also offers the least reusability because common operations such as creating parameters are usually done in each method.

  • Abstracted Providers . graphics/newterm.gif By relying on the key interfaces we discussed yesterday , a second approach is for the methods that make up the public interface of the data services tier to internally use a specially designed helper class I refer to as a provider factory to instantiate the actual provider used. This is a common object-oriented design pattern called the abstract factory pattern that can be used whenever your code needs to instantiate a related set of objects such as those from a particular provider (such as OleDbConnection , OleDbCommand , and so on). This approach allows the data access classes to be generic in terms of the provider, making it easier to switch providers down the road if necessary. We'll discuss this approach in detail on Day 17.

  • Internal Data Factory . A third approach is to not only abstract the provider internally in the data services tier, but also to abstract the most common algorithms performed. For example, many methods in the public interface of the data services tier need to create a connection object, create a data adapter and pass it the stored procedure, create parameter objects, populate the parameters and associate them with the command, and finally fill a DataSet using the data adapter. All this can be abstracted into an internal data factory class, relieving the burden from the developer. In addition, an internal data factory gives you the opportunity to add additional features, such as the caching of command objects when they are built. We'll discuss this approach in detail on Day 18.

As mentioned previously, regardless of which approach you take to build your data services tier, you can take advantage of implementation inheritance and build one or more base classes that take care of some of the common infrastructure-type work that any class in the data services tier might need, such as connection management and logging.

for RuBoard


Sams Teach Yourself Ado. Net in 21 Days
Sams Teach Yourself ADO.NET in 21 Days
ISBN: 0672323869
EAN: 2147483647
Year: 2002
Pages: 158
Authors: Dan Fox

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net