Practical ASP.NET

Object-Oriented Programming for the ASP.NET Developer

Peter Vogel continues to look at the basics of O-O development to support the ASP.NET ObjectDataSource.

In my last column (Supporting the ObjectDataSource), I started looking at the code necessary to create objects that would work with the ObjectDataSource. In that column, I looked at creating an object factory class with methods that would convert rows in a Customer table into Customer objects, suitable for integration into an ASP.NET page using the ObjectDataSource. This column looks at the data class for those Customer objects.

A Simple Data Class
In my factory methods, I used this line of code to create my Customer object:

   cst = New Customer(rdr(0),  rdr(1),  rdr(2), …)

In that line of code, I passed each of the fields in the row that I had retrieved from the Customers table to my class' constructor. That constructor (and its enclosing class) would look like this (I've only included support for three columns of the table in this example):

Public Class Customer

Private _CustomerId As String
Private _CompanyName As String
Private _ContactName As String

Public Sub New()

End Sub

Public Sub New(ByVal CustomerID As String, 
   ByVal CompanyName As String, 
   ByVal ContactName As String)
  _CustomerId = CustomerID
  _CompanyName = CompanyName
  _ContactName = ContactName
End Sub

As you can see, all I'm doing in the class' constructor is capturing the values passed to it and storing them in private class-level variables (fields).

The rest of the Customer data class consists of properties to return those values stored in those fields. Here's a typical example:

Public Property CompanyName() As String
        Get
            Return _CompanyName
        End Get
        Set(ByVal value As String)
            _CompanyName = value
        End Set
End Property

If you want to support validating data in the middle tier, you'll put code to check the data entering your application in these properties. You might also declare some properties as readonly to prevent users from changing the value in the user interface (e.g. the property that returns the table's primary key). Alternatively, you could count on the validation in the page itself or in the database to keep users from changing any bad values.

If you're going to use the object from code rather than just tie it to the ObjectDataSource, there's some other enhancements you could consider. You might, for instance, add additional methods and properties to support setting multiple inter-related properties in one call. You could also add a property to track the status of the object (e.g.: Is this Customer to be deleted in the database?).

Typically, this class doesn't see as many changes as the Factory class does over time. A new property will occasionally be added to support changes in the database, validation code in some property will be enhanced, or a new method added to simplify working with the class.

Extending the Data Class
In the real world, it's an unusual application where the screen display matches the table design. For instance, if you're retrieving a SalesOrderLine, that table probably includes a column that holds the ProductId. However, in the user interface, you don't want to display just the ProductId: Your users want to see the ProductName.

This is part of the beauty of the Factory Method design pattern: you can extend your factory methods to incorporate whatever information you need in your data class. For instance, I might have a SalesOrderLineFactory with a method called GetSOLineBySOWithProdName. That method would look like this:

Shared Function GetSOLineBySOWithProdName( _
   ByVal SalesOrderNumber As String) As List(Of SalesOrderLine)
Dim rdr As SqlDataReader
Dim con As New SqlConnection(…connectionstring…)
Dim cmd As SqlCommand = con.CreateCommand()

md.CommandText = "Select * From SalesOrderLine s " & _
                                  "   Inner Join Products p " & _
                                  "     On s.ProductId = p.ProductId " & _
                                  " Where SalesOrderNumber = @SONumber"
cmd.Parameters.AddWithValue("SONumber", SalesOrderNumber)

Dim lst As New List(Of SalesOrderLine)
Dim sol As SalesOrderLine

con.Open()
rdr = cmd.ExecuteReader()
Do Until rdr.Read
    sol = New SalesOrderLine(rdr(0), rdr(1), rdr(2))
    lst.Add(sol)
Loop

Return lst

End Function

Extending the data class with related information is just one solution to the mismatch that typically exists between your business objects and your user interface. I'm going to look at a more sophisticated solution (involving another design pattern, I'm afraid) in a later column.

By the way, if you're starting to think, "Gee, all this code looks very much alike..." well, you're right. And coding these objects can get really boring really fast. It was repetitive code like this that drove me to create my first code generation solutions. In the meantime, of course, smarter people than me were creating object relational mapping (ORM) tools that would generate this code for a wider variety of scenarios than I was willing to handle.

However, my goal in these columns is more focused: To support the ObjectDataSource. In my next column I'll return to that mission showing how to extend the Factory objects to support updates.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Full Stack Hands-On Development with .NET

    In the fast-paced realm of modern software development, proficiency across a full stack of technologies is not just beneficial, it's essential. Microsoft has an entire stack of open source development components in its .NET platform (formerly known as .NET Core) that can be used to build an end-to-end set of applications.

  • .NET-Centric Uno Platform Debuts 'Single Project' for 9 Targets

    "We've reduced the complexity of project files and eliminated the need for explicit NuGet package references, separate project libraries, or 'shared' projects."

  • Creating Reactive Applications in .NET

    In modern applications, data is being retrieved in asynchronous, real-time streams, as traditional pull requests where the clients asks for data from the server are becoming a thing of the past.

  • AI for GitHub Collaboration? Maybe Not So Much

    No doubt GitHub Copilot has been a boon for developers, but AI might not be the best tool for collaboration, according to developers weighing in on a recent social media post from the GitHub team.

  • Visual Studio 2022 Getting VS Code 'Command Palette' Equivalent

    As any Visual Studio Code user knows, the editor's command palette is a powerful tool for getting things done quickly, without having to navigate through menus and dialogs. Now, we learn how an equivalent is coming for Microsoft's flagship Visual Studio IDE, invoked by the same familiar Ctrl+Shift+P keyboard shortcut.

Subscribe on YouTube