Fitch & Mather Stocks 2000: Core Components

Scott Hernandez
Vertigo Software, Inc.

November 1999

Summary: This article describes how the Fitch & Mather Stocks 2000 (FMStocks 2000) core components were ported from the original FMStocks 1.0 code, while explaining how and why new technologies were added to these components. (9 printed pages)

Contents

What Is the Core of Fitch & Mather Stocks 2000?
Migrating to Windows 2000
Using the COM+ Services 1.0 Type Library
Implementing IObjectConstruct
Redesigning the Core for Future Development
Using the Server Script Object Tag
Summary
About the Author
For More Information

What Is the Core of Fitch & Mather Stocks 2000?

The core components were created for the original FM Stocks 1.0 sample. Core components include the FMStocks Business Logic and data access layers.

Important   This article assumes the reader is familiar with the FMStocks 1.0 architecture. Complete documentation for Fitch & Mather Stocks 1.0 can be found at “Fitch & Mather Stocks: Start Here.”

In the following discussion, you will see a comparison between FMStocks 1.0 and the core components of FMStocks 2000. There are very few differences in the core components.

The FMStocks 2000 core components contain all of the services necessary for the core Web application. In later articles, we will address how we use these core services to quickly add new features to our application. In particular, we will be able to reuse our general data access component so that future SQL-based data access layers need not reimplement their own solutions. For more information on this topic, you can skip to Redesigning the Core for Future Development.

Note   asterisks (*) in the table below indicate elements that are new or changed for FMStocks 2000.

FMStocks 2000
Core areas
FMStocks 1.0 FMStocks 2000
Presentation Tier ASP Pages ASP Pages*
(New style and color scheme.)
ISAPI Security Filter*
(See other articles.)
Middle Tier(s): Business Logic FMStocks_Bus.Account
FMStocks_Bus.Broker
FMStocks_Bus.Ticker
FMStocks_Bus.Version
FMStocks_Bus.Account
FMStocks_Bus.Broker
FMStocks_Bus.Ticker
FMStocks_Bus.Version*
(Additional Methods)

New Components for Store*
(See Store and Office articles.)

Data Access Layer FMStocks_DB.Account
FMStocks_DB.Broker
FMStocks_DB.Positions
FMStocks_DB.Ticker
FMStocks_DB.Tx
FMStocks_DB.TxNew
FMStocks_DB.Version
FMStocks_DB.Account
FMStocks_DB.Broker
FMStocks_DB.Positions
FMStocks_DB.Ticker
FMStocks_DB.Tx
FMStocks_DB.TxNew
FMStocks_DB.Version
FMStocks_DB.DBHelper*
(Replaces functionality from shared database.bas.)

New Components for Store*
(See Store and Office articles.)

Database Tier 19 Stored Procedures

7 Tables

30 Stored Procedures*
(11 new for Store Shopping Cart.)

10 Tables*
(2 for Store, 1 for Historical data.)

External Services* None Office 2000 Clients

Offline Analysis Tool

Windows® CE Client

FMStocks Store


Migrating to Windows 2000

One of our primary goals for migrating FMStocks from Windows NT® 4.0 to Windows 2000 was to create documentation and sample code to be used as a guide. It was important to find out if the FMStocks 1.0 binaries would run on Windows 2000 as they did on Windows NT 4.0. We installed FMStocks 1.0 binaries on a Windows 2000 Server with RC1. We started testing the application and found that everything worked, without any changes.

We started to read the SDK notes for COM+, Windows NT and ADO to see if there were any concerns or suggestions to note. We found a few good suggestions and comments.

The VB New Keyword

The New keyword now supports the current object context to flow other components. In our components, we changed the way we created other components to the following form:

    ‘ Create the ADO objects
    Dim rs As ADODB.Recordset
    Dim cmd As ADODB.Command
    Set rs = New ADODB.Recordset
    Set cmd = New ADODB.Command

Note   If you Dim the object as New, the Microsoft Visual Basic® compiler wraps each use of the object with a conditional statement. However, dimensioning and creating the object on two different lines removes this ambiguity from the compile.

Class_Initialize vs. ObjectControl_Activate

When writing components that are located and operate in MTS, now COM+, use ObjectControl’s Active and Deactivate events to indicate when to create and destroy class-level variables, and objects. In Visual Basic, the Class_Initialize procedure is called for each class when the class is created. The Class_Terminate performs a similar function prior to the destruction of the class or component. These functions are similar to the concept of constructors and destructors in nature, but you cannot pass variables during these class events. These class events are called before, and after, the ObjectControl events, corresponding the event.

One of the key advantages for using the ObjectControl events is the ability to monitor when you are in a COM+ application. In the ObjectControl_Activate event, you can get an object context, and the Security Context, for the lifetime of your object. It is suggested that in your ObjectControl_Activate you reference GetObjectContext to store for later use.

Below is an example of the way to test this:

Private Sub Class_Initialize()
   PriDebugPrint “Class Initialize”
End Sub
Private Sub ObjectControl_Activate()
   PriDebugPrint “ObjectControl Activate”
End Sub
Private Sub ObjectControl_Deactivate()
   PriDebugPrint “ObjectControl Deactivate”
End Sub

Private Sub Class_Terminate()
   PriDebugPrint “Class Terminate”
End Sub

Debug Results:

Class Initialize 
ObjectControl Activate
ObjectControl Deactivate
Class Terminate

Note   Visual Basic components cannot be object pooled by COM+ because of the Threading Model, Single Threaded Apartment (STA). The result from the ObjectControl_CanBePooled function is ignored because of this.

For more information about current issues with Class_Initialize see the Microsoft Knowledge Base article Q170156.

Using the COM+ Services 1.0 Type Library

The COM+ Type library includes all of the functionality that was in the MTS Type Library while adding many new features such as Queued Components (QC), the Object Construction String, more COM+ Security Objects, and Loosely Coupled Events (LCE). It is the only type library you need to include as you work with these technologies.

Note   The COM+ Type Library replaces the MTS Type Library. In fact, the COM+ Type Library CLSID is the same as that of the MTS Type Library. However, once you start developing for a COM+ application using any new COM+ Service, there is no easy way to move the code back to Windows NT 4.0.

Implementing IObjectConstruct

IObjectConstruct is a useful interface that COM+ supplies. It allows an administrator to pass a string to components every time they are created. This general feature allows us to remove the FMStocks 1.0 requirement of hard-coding the database connection string and having it passed to the Web application at run time. With the IObjectConstruct interface, the system administrator can configure deployment settings. In fact, the connection string can be changed while the COM+ application is running.

Let’s look at how we implemented our new data access layer helper class to take advantage of this new feature. FMStocks 1.0 uses a function in a module called DATABASE.BAS to hold the database connection string (GetConnectionString()). This solution works fine, but it requires that we rebuild the component if we want to change the connection string. Rebuilding the component makes it less than easy to reconfigure the location of the database at design time.

While developing this function, we tried getting the connection string from the registry, from the Shared Property Manager of our MTS Package, from the calling component (that is, ASP, or the business logic), and even from a configuration file. The IObjectConstruct interface has as a property that solves this problem elegantly for us. The administrative interface that sets the constructor string is shown in Figure 1.

Figure 1. Configuring the constructor string

To help us get multiple parameters from the construction string, we wrote a simple string parser. We chose to use a simple Comma Separated Value (CSV) list with key-value pairs. The code below shows the implementation of IObjectConstruct_Construct for our DBHelper class.

Private Sub IObjectConstruct_Construct(ByVal pCtorObj As Object)
    ‘eval construction string and find out what the admin wants us to do
    Dim arrParams, x As Integer    
    arrParams = Split(pCtorObj.ConstructString, “,”)
    For x = LBound(arrParams) To UBound(arrParams)
        Select Case UCase(GetKey(arrParams(x)))
            ‘should we use a new Connection String?
            Case UCase(“ConnectionString”)
                m_ConnectionString = GetValue(arrParams(x))
            Case UCase(“Server”)
                m_DBServer = GetValue(arrParams(x))
        End Select
    Next
End Sub

Additional places we could have used Object Construction Parameters:

Place Purpose
Creating a new account Set the new balance.
Placing a trade Set the commission.
Disable trading Shut down trading, but allow portfolio viewing.

Redesigning the Core for Future Development

During our architecture review for FMStocks 1.0, we listed the services that we could reuse in future development. The list looked something like this:

Tier Object(s) Use
Presentation (ASP) Template.asp This page includes all of the Server-Side Includes (SSI) that we need for any new pages to fit in our Web sites’ general look and feel.
Business Logic Account.* The Account object gives us the ability to Verify a user’s identity, show account balances, and view their current positions.
Data Access Account.* Used by Business Logic.
Data Access DBHelper.bas This object encompasses the functions used to directly access the data provider.
Database Accounts Table Used by components.
Database Various Stored Procedures Used by components for data access.

FMStocks 1.0 was developed to make a good base for extending. We wanted to create a complete Windows DNA application that could be easily and quickly replicated by developers. We took a hard look after the code was released for any simplification opportunities.

Using the Server Script Object Tag

In FMStocks 1.0, we created our objects from ASP by calling Server.CreateObject(). We were very careful to use this function instead of the global CreateObject() call. Server.CreateObject() allowed ASP to instantiate an object whose object context and transaction context could be passed to the new object. It allowed for the object context to flow to any object created on that page.

In FMStocks 2000, we created objects using the HTML object tag. This allows the ASP Script engine to manage when the objects are created and destroyed. It also lets us take advantage of a new error handling feature in Internet Information Server (IIS) 5.0. The new error handling feature allows us to call a central page with any untrapped errors. In our case, if an object isn’t installed on the server, we can catch that error and display a user-friendly and consistent error message indicating that the site is under repair.

Another benefit of object tags: Because we put all of the object tags at the top of the page, it is very easy to open an ASP page and immediately tell which objects are being used.

Note   These are server object tags, not to be confused with client object tags.

‘ OBJECT tag example:
‘ Create an ADODB.Connection Object when needed
<OBJECT RUNAT=server PROGID=ADODB.Connection id=conn> </OBJECT>

When ASP encounters an object tag, the object isn’t actually created at that time. The object isn’t actually instantiated until the first method, or property, is called. If you never call the object, then it will never be created. Since you don’t need to manually destroy it, you will always have a valid object for the scope of the page. You will not get an error like “object doesn’t exist” if you use server object tags. This also helps by eliminating the need to create objects that may never be called. Object creation is one of the most costly operations; it is one of the reasons why we use a COM+ Application. Each time we can cut out an unnecessary object creation, we should do it.

Note   If you attempt to destroy an object created with the object tag you generate an ASP preprocessor error. ASP will not let you set any object created with the object tag equal to nothing.

Summary

While porting FMStocks 1.0 to Windows 2000 and COM+, we learned some important lessons. This article, along with others in this series, is here to guide you to a smooth migration from Windows NT 4.0 and Windows 9.x development into Windows 2000. The lessons we learned are:

About the Author

Scott Hernandez is a Senior Software Developer at Vertigo Software, Inc. As an MVP, he can be found roaming the Microsoft development newsgroups.

He and other Vertigo developers on FMStocks can be reached at fmstsocks@vertigosoftware.com or on the Web at http://www.vertigosoftware.com/.

For More Information