Steve Kirk
Microsoft Developer Network
March 1999
Summary: Describes the migration strategy for the Duwamish Books sample Phase 4 Business Logic Layer (BLL) component. (4 printed pages) Discusses immutability of published COM interfaces, binary compatibility and development tools, and the Duwamish Phase 4 BLL and migration components.
No matter how well a business system is planned, new requirements or a better understanding of existing requirements will motivate change. As the fictional Duwamish Books organization prepared to do business online, it became clear that a few "minor changes" would enable new features, simplify localization, and increase performance. A database overhaul was a major part of the migration and included entity changes, schema normalization, and optimization (see "Normalizing the Duwamish Books, Phase 4 Database").
In this article, I'll describe how the Business Logic Layer (BLL) Component Object Model (COM) component for Phase 4 of Duwamish Books was upgraded from the Phase 3 version—without requiring any change to legacy applications written to earlier versions of the BLL. For a discussion of the design of the Phase 3 BLL component, see my article"Abstracting Business Transactions." Figure 1 shows how the upgraded BLL and database support both the new online business and existing store operations using the legacy applications.
Figure 1. The Phase 4 BLL and database replace earlier components without requiring any changes to legacy applications.
The BLL simplifies applications by abstracting business transactions so that client applications can execute those transactions (for example, inserting a sale) without concern for implementation details beyond the abstraction. Code in the client application merely prepares the data that represents a sale (as documented in the Phase 4 BLL API) and passes the data to InsertOrder to execute the transaction.
BLL code is packaged in a COM component. When a BLL component is published, the binary interface exposed by the component is set in concrete. Client applications can then be safely bound to this binary interface, which is guaranteed, by the rules of COM, to be immutable.
In addition to an immutable binary interface, COM components contain code that does the work behind the interface. The implementation behind the interface is not governed by the rules of COM. This allows equivalent services to be offered by providers using vastly different code or technology behind the interface.
The Phase 4 BLL contains two classes that provide different APIs. One class, (cBusLogic) is optimized for the Phase 4 application. The other class (cBusLogic_3) is equivalent to the legacy, Phase 3, BLL. The Phase 4 BLL API documents the methods of cBusLogic. The migration components maintain binary COM compatibility with legacy BLL components and are, in turn, clients of the legacy-equivalent implementation provided by cBusLogic_3. The Phase 3 BLL API guide documents the functionality exposed by the migration components.
Migration components used with the Phase 3 and Phase 3.5 clients are in-process servers that effectively replace the legacy BLL components. These components match client applications with various BLL implementations. Migration components offer advantages over the strategies for swapping BLL components that we used in Phase 3 and Phase 3.5.
The Phase 3 clients contained early bound references to the Microsoft® Visual Basic® version of the Phase 3 BLL (db3vbbll.dll) and required recompilation to use the Microsoft Visual C++® version of the BLL that we also supplied with the sample. See Michael Zonczyk's discussion of component compatibility in Phase 3 in "Implementing the Duwamish Books Business Logic Layer in Visual C++." Migration components having binary interface compatibility with db3vbbll.dll and meeting the specifications in Table 1 would allow BLL implementation swapping by merely registering the migration component.
Table1. Migration Components for Phase 3 Clients
Migration component having binary interface compatibility with db3vbbll.dll | Containing early binding to: | Uses this implementation: |
bllmig1.dll | Db4bll.cBusLogic_3 (legacy compatible implementation) in d4vbbll.dll | Use Phase 4 BLL and Data Access Layer (DAL) components under MTS, with phase 4 database |
Bllmig2.dll | D35bll.cBusLogic in d35vbbll.dll or d35vcbll.dllor | Use Phase 3.5 BLL and Data Access Layer (DAL) components under MTS, with phase 3/3.5 database |
Bllmig3.dll | Db3bll.CbusLogic in db3vcbll.dll | Use Phase 3 VC BLL |
The Phase 3.5 clients were built using late binding on the BLL to allow swapping of BLL component versions without recompiling. Although late binding simplifies component version swapping, there is a performance cost associated with late binding that would be avoided by using early binding and migration components. For more on the BLL component swapping strategy used in Phase 3.5, see Dale Smith's discussion of BLL object instantiation in "Remoting Duwamish Components."
Maintaining COM interface identifiers is different in Visual Basic than in Visual C++ because these tools support different development models. In Visual C++ the developer has more low-level control than in Visual Basic. Globally unique identifiers (GUIDs) that serve as COM interface identifiers (IIDs) only change when the developer explicitly changes them. Responsibility for following the rules of COM is with the Visual C++ developer—the tool doesn't complain if the developer wants to break the rules. Visual Basic, however, makes it harder for a developer to break the rules of COM. Visual Basic generates new GUIDs whenever the component is compiled unless the developer is very explicit about maintaining binary compatibility with a previously compiled component. If any of the component's public COM interfaces have been changed, Visual Basic issues stern warnings about breaking COM compatibility before allowing the developer to insist and change a previously published COM interface.
Changes to the database and business logic layer of an enterprise application present migration issues for existing clients. The rules of the Component Object Model (COM) provide specific direction for developers regarding the immutability of previously published COM interfaces. Beyond the immutability of interfaces, compatibility requires that an equivalent implementation be provided behind those interfaces to complete the implementation of a compatible version. Finally, migration components provide a binary-compatible substitute for the legacy component that calls the appropriate new implementation. Migration components support early binding on the client applications and, therefore, can provide better overall performance than a strategy of late binding on the client, which would mitigate some compatibility issues between server component versions.
Comments? We welcome your feedback at duwamish@microsoft.com.