The Business Objects and Assemblies


Four business objects written in C# provide the various ASP.NET pages with all the business logic and data access code they require. As all of the .NET classes are fairly similar in terms of structure and the ADO.NET code they use to access the SQL server database, we won't review every single method of every single object. Instead you will look at one of the components in detail ( ProductsDB ) to see the basic structure of the components, and then use the ILDASM utility to show the methods and properties of each of the remaining business objects for reference purposes. As you encounter pages that use these functions, we will expand on their purposes.

ProductsDB Business Object

The ProductsDB class provides functions for retrieving product information. The complete C# code for the class is shown here:

  using System;   using System.Data;   using System.Data.SqlClient;     namespace IBuyAdventure   {   public class ProductsDB   {   string m_ConnectionString;   public ProductsDB( string dsn ) {   m_ConnectionString = dsn;   }     public DataSet GetProduct(string productCode) {     SqlConnection myConnection = new SqlConnection(m_ConnectionString);   SqlDataAdapter sqlAdapter1 = new SqlDataAdapter("SELECT * FROM "   + "Products WHERE ProductCode='"+productCode+"'", myConnection);     DataSet products = new DataSet();   sqlAdapter1.Fill(products, "products");     return products;   }     public DataSet GetProducts(string category) {     SqlConnection myConnection = new SqlConnection(m_ConnectionString);   SqlDataAdapter sqlAdapter1 = new SqlDataAdapter("SELECT * FROM "   + "Products WHERE ProductType='"+category+"'", myConnection);     DataSet products = new DataSet();   sqlAdapter1.Fill(products, "products");     return products;   }   public DataSet GetProductCategories() {     SqlConnection myConnection = new SqlConnection(m_ConnectionString);   SqlDataAdapter sqlAdapter1 = new SqlDataAdapter("SELECT DISTINCT "   + "ProductType FROM Products", myConnection);   DataSet products = new DataSet();   sqlAdapter1.Fill(products, "products");   return products;   }   }   }  

This class has four methods, including the constructor:

  • ProductsDB :Initializes the class with a data source string

  • GetProduct :Returns a dataset containing details for a single product

  • GetProducts :Returns a dataset containing the details for all products in a specified category

  • GetProductCategories :Returns a dataset containing the list of product categories

The first three lines of the component declare the namespaces used:

 using System; using System.Data; using System.Data.SqlClient; 

All of the class files have these lines and they indicate that the application is using the standard system namespace, the namespaces for ADO.NET, and the SQL Server specific parts of ADO.NET ( System.Data.SqlClient ). The application uses the SQL Server specific elements of ADO.NET because they provide high performance SQL Server access using TDS (Tabular Data Stream) via the classes SqlConnection and SqlDataAdapter . If the application needed to support a different back-end database, the developer could recode the classes to use the OleDbConnection and OleDbDataAdapter classes, which perform database access through OLEDB. These classes were discussed in Chapter 8.

One important point to note about all of the ADO.NET code in the business object is that it does not contain any exception handlers. It is therefore up to the code that uses these classes to catch exceptions like SqlException , which can be thrown if any error occurs when performing the data access (such as the existence of duplicate rows, and so on). No exception handling is included in these ASP.NET pages (to keep them terse), but the basic format is shown here:

  try   {   someObject.SomeMethodUsingAdoDotNet()   }   catch (SqlException e)   {   if (e.Number == 2627)   Message.InnerHtml = "Record exists with the same primary key";   else   Message.InnerHtml = e.Message;   }  

This code checks for a known SQL Server error code using the SqlException Number property. If the error code the app is checking for is matched, it displays a custom error message. If the known error code is not encountered , it displays the exception's Message property. The Message property of an exception object typically contains very descriptive and helpful text that can help resolve a problem quickly. In your applications, you are unlikely to check for specific error codes, unless you want to perform some type of action. For example, you may check for the preceding error code if you want to delete a row that may already exist.

Important

You should always proactively add exception handling code to your production applications. The ADO.NET classes (including SqlException ) are located in the assembly System.Data.dll . Use the IL Disassembler ( ildasm.exe ) tool, the WinCV class viewer, or the class browser example from the Quick Start to explore the classes in more detail.

The Connection String Constructor

The ProductsDB class has a constructor that accepts the connection string used to establish a connection to the back-end database. By passing the string in like this, the app prevents people from forgetting to specify it, and hopefully prevents the business objects from containing hard coded strings, which is always bad practice.

The string passed in is stored in the member m_ConnectionString in the constructor code:

 ... string m_ConnectionString;      public ProductsDB( string dsn ) {    m_ConnectionString = dsn; } ... 

The m_ConnectionString member is then used when constructing the SqlConnection object:

 public DataSet GetProduct(string productCode) {         SqlConnection myConnection = new SqlConnection(m_ConnectionString);    SqlDataAdapter sqlAdapter1 = new SqlDataAdapter("SELECT * FROM "       + "Products WHERE ProductCode='"+productCode+"'", myConnection);         DataSet products = new DataSet();    sqlAdapter1.Fill(products, "products");         return products; } 

Anybody using the ProductsDB business object (and any of the other business objects) must therefore pass the connection string when creating an instance of the class:

  IBuyAdventure.ProductsDB inventory =new IBuyAdventure.ProductsDB(getConnStr());  

The getConnStr function in this example retrieves the connection string from the web.config file:

  <configuration>     <appSettings>   <add key="connectionString"   value="server=localhost;uid=sa;pwd=;database=IBuyAdventure" />   <add key="specialOffer" value="AW048-01" />   </appSettings>   ...  

By using the web.config file to store the connection string for the components (and, in the previous example, another application-level value) the application does not have connection strings duplicated throughout business objects and ASP.NET pages, making it much easier to manage the connection string should you decide to rename the database or change any of the connection string properties.

Important

The getConnStr function is implemented using a 'code behind' class that will be reviewed when creating the Page class. You could, alternatively, use an include file to define such functions in your application, but the 'code behind' approach is my preferred option.

After reviewing the ProductsDB class, let's take a brief look at a couple of ILDASM screenshots showing the methods for the other business objects.

Figure 24-2 shows the ILDASM output for the IBuyAdventure.dll assembly:

click to expand
Figure 24-2:

The ILDASM Output for IBuyAdventureCart.dll

Figure 24-3 shows the ILDASM output for the IBuyAdventureCart.dll assembly:

click to expand
Figure 24-3:

Assemblies

As discussed in Chapter 17, assemblies are the key deployment mechanism in ASP.NET applications. As shown in Figure 24-4 the business objects for IBuyAdventure.NET are divided into two assemblies that are both dependent upon the System.Data.dll assembly, because they use ADO.NET.

click to expand
Figure 24-4:

The IBuyAdventureCart.DLL contains the CartDB business object, which is used for manipulating the shopping cart. This is dependent upon the ProductsDB class contained within the IBuyAdventure.DLL assembly.

Important

Although assemblies have a .dll extension, they are, for the most part, not DLLs! The extension was kept only to aid interoperability between COM+ managed code and classic COM unmanaged code.

The IBuyAdventureCart.dll assembly isn't strictly necessary, but it does show that partitioning classes into different assemblies in an ASP.NET application isn't a difficult task. The decision as to when to create assemblies will typically be influenced by a number of real life factors:

  • The functionality of the classes within the assembly :Assemblies should ideally contain functionally related classes.

  • The number of developers working on an application :Assemblies are key units of deployment in ASP.NET applications, so it makes sense for different development teams to create their own assemblies to ease co-development.

Compiling the Assemblies

All of the business object sourcecode for the IBuyAdventure application is located in the components directory. This directory contains the file make.bat that uses the C# command line compiler ( csc.exe ) to create the two assemblies:

  csc /out:..\bin\IBuyAdventure.dll /t:library productsdb.cs ordersdb.cs   usersdb.cs /r:System.Data.dll,System.dll,System.Xml.dll     csc /out:..\bin\IBuyAdventureCart.dll /t:library cartdb.cs   /r:System.Data.dll,System.dll,System.Xml.dll /r:..\bin\IBuyAdventure.dll  

The first statement compiles the business objects ProductsDB , OrdersDB , and UsersDB, which are located within the files productdb.cs , ordersdb.cs , and usersdb.cs respectively. The output from this statement is the IBuyAdventure.dll assembly. The second statement compiles the business CartDB , which is located in the file cartdb.cs . The output from this is the IBuyAdventureCart.dll assembly. Both assemblies are compiled into the ASP.NET application bin directory so that they are available to the ASP.NET pages.

Naming Conventions

The IBuyAdventure business objects ProductsDB , OrdersDB , and UsersDB are declared within the namespace IBuyAdventure . This reflects the name of the assembly they are contained in, making it easy to locate and determine what files to ship when it comes to deploying an application that contains pages that are dependent upon those classes. The same naming convention applies to the CartDB business object, which is declared within the namespace IBuyAdventureCart , and contained in the assembly IBuyAdventureCart.dll . Microsoft also uses this naming convention for most of its assemblies. The exceptions to the rule are core classes, such as strings, which tend to live in assemblies called mscor [*] .dll .




Professional ASP. NET 1.1
Professional ASP.NET MVC 1.0 (Wrox Programmer to Programmer)
ISBN: 0470384611
EAN: 2147483647
Year: 2006
Pages: 243

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