Sample Application

[Previous] [Next]

I'm drawing from the "Scenario" section of this chapter to provide a sample that includes a User Profile Service framework that resides in an ActiveX DLL, and an Excel client application that is a consumer of this framework. To recapitulate, this User Profile Service framework allows you to create user profile objects, as well as store and retrieve those objects to and from a repository (UserProfileRepository). What the Excel client does with this information is of no concern to the framework. The intended purpose of the framework is to provide a uniform approach to maintaining user profile settings of practically any variation. These settings are packaged in a UserProfile class object that is flexible enough to contain any amount of attributes of generally any type. The UserProfileRepository interface serves as a persistent object service for UserProfile objects.

Concrete classes inherit the UserProfileRepository interface, providing their own implementations that primarily involve storing and retrieving the state of a UserProfile object to and from a designated data source. A typical repository can store and retrieve settings to and from a SQL Server or Access database. A concrete repository class relies on interface inheritance to reuse the UserProfileRepository interface. As mentioned earlier, not all ActiveX-enabled programming languages support inheritance. Therefore, although such programming languages could be used to create client applications that are consumers of the User Profile Service framework, the languages could not be used without the inheritance language feature to extend the framework to support concrete repository classes.

Based on that premise, the User Profile Service framework sample I've included implements the Bridge design pattern, which essentially creates a bridge between the UserProfileRepository abstract interface and a concrete Excel workbook repository class that contains the implementation intended for that interface.

In this sample, the Excel client uses the User Profile Service framework to retrieve predefined user profile settings from an Excel workbook repository class object that are used for ODBC-based applications. The client's only function at this point is to create data source names (DSNs) in your operating system that can be referenced by ODBC-based applications. Careless programmers usually don't check for the existence of DSNs that are required for their ODBC-based applications to function. You can use this sample User Profile Service framework to guarantee that the DSNs required by your application do exist.

To run this sample,

  1. Ensure that Excel 97 or later and Data Access Objects (DAO) 3.5 or higher are installed on your PC.
  2. In the directory where the samples for this chapter have been copied to your PC (C:\VBDesign\Bridge by default), register UserProfileFx.dll by typing the following at a command prompt: regsvr32 UserProfileFx.dll.
  3. Start Excel.
  4. Open the UserProfile.xls sample file.

If all is well, a workbook will appear in Excel that resembles Figure 5-3.

click to view at full size.

Figure 5-3. An Excel workbook used as a user profile repository.

On the worksheet under the area labeled User Profile Repository Information, you will find the user profile settings. On the right side of the worksheet under the Try Me section, click the button labeled Register DSN, which brings up the User Profiles dialog box. (See Figure 5-4.)

Figure 5-4. Dialog box containing user profile settings retrieved from the Excel workbook repository.

This dialog box uses the User Profile Service framework to display the various user profile settings by name that are located on the left side of the worksheet. Clicking the OK button will result in an attempt to create a DSN based on the currently selected user profile. You can see whether the attempt was successful in the User DSN tab of the ODBC Data Source Administrator dialog box. (You can invoke this dialog box by double-clicking the ODBC icon located in the Control Panel.) For instance, if you selected New_York, you would find a DSN entry in the dialog box labeled WTC. (See Figure 5-5.)

click to view at full size.

Figure 5-5. The ODBC Data Source Administrator dialog box serves as the user interface to the ODBC administrator.

This sample illustrates the advantages of a User Profile Service framework, but it is more important for us to understand how the framework is extended to support a repository workbook class created in Excel VBA by applying the Bridge design pattern. The following sections briefly describe all the Bridge design pattern participants that facilitate extensibility of the User Profile Service framework in this sample. Refer to the Bridge folder on the companion CD for a full disclosure of the source code.

The UserProfileRepository Interface

The UserProfileRepository (abstraction) class is an abstract interface that defines how to persist UserProfile objects to a repository. Because the interface is abstract, it contains no implementation of its own. Concrete classes inherit this interface, providing unique implementation to store, retrieve, and remove user profiles from a particular data source. In the UserProfileFx ActiveX DLL project, I took these steps:

  1. Created a class module.
  2. Changed the Name property value to UserProfileRepository.
  3. Changed the Instancing property value to PublicNotCreatable.
  4. Defined the interface methods without implementation, as follows:
  5.  ' Class Name: UserProfileRepository Option Explicit Public Function GetKeys(Keys() As String) As Long End Function Public Function GetUserProfile(Key As String) As UserProfile End Function  

The UserProfileRepBridge Class

The UserProfileRepBridge (bridge) class is a concrete class that inherits the UserProfileRepository abstract interface. The implementation of this class is special because, instead of persisting UserProfile objects to a particular data source, it delegates the task by publishing events to subscribing implementors. In the UserProfileFx ActiveX DLL project, I took these steps:

  1. Created a class module.
  2. Changed the Name property value to UserProfileRepBridge.
  3. Changed the Instancing property value to PublicNotCreatable, permitting UserProfileRepBridge class objects to be created only via the UPFactory class object, which is discussed in Chapter 8, "Object Factory."
  4. Inherited the UserProfileRepository interface by using the keyword Implements.
  5. Defined corresponding events for each method in the UserProfileRepository interface.
  6. Published a specific event for each method implementation of the UserProfileRepository interface.

The resulting UserProfileRepBridge class looks like this:

 ' Class Name: UserProfileRepBridge Option Explicit ' Inherit the UserProfileRepository interface. Implements UserProfileRepository ' Define an event that corresponds to each property and method of ' the UserProfileRepository interface. Public Event GetKeys(Keys() As String, ByRef KeyCount As Long) Public Event GetUserProfile(Key As String, ByRef UP As UserProfile)  ' Implement all properties and methods of the ' UserProfileRepository interface. In the implementation of each, ' publish the corresponding event. Private Function UserProfileRepository_GetKeys(Keys() As String) _ As Long RaiseEvent GetKeys(Keys, UserProfileRepository_GetKeys) End Function Private Function UserProfileRepository_GetUserProfile( _ Key As String) As UserProfile RaiseEvent GetUserProfile(Key, _ UserProfileRepository_GetUserProfile) End Function  

The WorkbookRepImpl Class

The WorkbookRepImpl (implementor) class is defined within Excel in VBA. The WorkbookRepImpl class is a concrete class that defines an Excel workbook repository implementation intended for the UserProfileRepository interface. WorkbookRepImpl subscribes to events published by a given UserProfileRepBridge class object. Event subscription is optional; therefore, as is the case in this sample, WorkbookRepImpl is subscribing to only two of the four events. Upon notification, its event handler is called automatically. Using the Visual Basic editor in the UserProfile Excel workbook project (UserProfile.xls), I took these steps:

  1. Created a class module.
  2. Changed the Name property value to WorkbookRepImpl.
  3. Declared a member variable of type UserProfileRepBridge using the keyword WithEvents. Doing so implicitly enables WorkbookRepImpl objects to subscribe to any events published by a given UserProfileRepBridge object they are referencing.
  4. Defined event handler methods only for events of interest to WorkbookRepImpl.
  5. Defined an Attach method, which allows WorkbookRepImpl objects to attach to any given UserProfileRepBridge object at run time. This action will invoke an implicit subscription for all events that have defined event handlers in WorkbookRepImpl.
  6. Defined a Detach method, which allows a client to request that a WorkbookRepImpl object release its reference to a UserProfileRepBridge object. This action will result in an implicit unsubscribe of all events. In addition, subscription cancellation will occur if the Attach method is passed Nothing or when the WorkbookRepImpl object is destroyed. Keep in mind that you do not have to call the Detach method to unsubscribe from one UserProfileRepBridge object before subscribing to another. Simply calling the Attach method with a reference to another UserProfileRepBridge object will implicitly cancel the previous subscription and subscribe to events from the new object.

Here is the resulting WorkbookRepImpl class:

 ' Class Name: WorkbookRepImpl Option Explicit Private WithEvents RepBridge As UserProfileFx.UserProfileRepBridge ' Attach Implementor to Bridge. Doing so will allow the ' Implementor object to subscribe to events published by the Bridge ' object. Public Sub Attach(upRepBridge As UserProfileFx.UserProfileRepBridge) Set RepBridge = upRepBridge End Sub ' Detach Implementor from Bridge. This results in an implicit ' unsubscribe of all events published by the Bridge object. Public Sub Detach() Set RepBridge = Nothing End Sub ' Implicitly subscribe to events GetKeys and GetUserProfile ' published by the Bridge object by defining the following event ' handlers respectively. ' Private Sub RepBridge_GetKeys(Keys() As String, KeyCount As Long) ' Excel implementation code located here.  End Sub Private Sub RepBridge_GetUserProfile(Key As String, _ UP As UserProfileFx.UserProfile) ' Excel implementation code located here  End Sub  



Microsoft Visual Basic Design Patterns
Microsoft Visual Basic Design Patterns (Microsoft Professional Series)
ISBN: B00006L567
EAN: N/A
Year: 2000
Pages: 148

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