Rogue Wave banner
Previous fileTop of DocumentContentsIndex pageNext file
Stingray Foundation Library User's Guide
Rogue Wave web site:  Home Page  |  Main Documentation Page

14.3 Using Property Bags in C++ Code

Although the SFL property bags implementation are intended to be used as an independent COM library, it is also possible to use the individual classes directly from source code in a C++ application when a flexible persistence mechanism needs to be put in place.

First, it is important to note that, even if used at the source code level, SFL's property bag implementations require some degree of COM support in order to work correctly. For example, the persistable objects need to implement the IUnknown interface and the corresponding IPersistXXX interface. Also, the data that will be stored in a property bag needs to be representable as a set of name-value pairs, where the values are of VARIANT-compatible types.

You can adapt your C++ objects by partially enabling just the COM needed to work with the property bags at a source code level. For example, Example 129 illustrates a C++ class CHybrid that combines the C++ interface mechanism based on the IQueryGuid interface, with an IPersistPropertyBag implementation put together using ATL as the COM framework.

Example 129: Enabling COM support for property bags within a C++ class

The IQueryGuid interface is used widely in SFL. See Chapter 3, "Interface-Based Programming," for more information. The class CHybrid utilizes the QueryGuid mechanism for C++ interface-based programming. However, when persistence was added, an IUnknown implementation was needed, as well as the interface querying based on the QueryInterface function used in COM. Since this is not a true COM class, it is not available for external instantiation and it doesn't have to deal with issues like apartments or contexts, thread models, or other COM-isms. Its lifetime does not even need to be managed by the reference counting mechanism. It needs only enough functionality to satisfy the expectations of the property bag:

Persistable objects do not need to have their COM class factory registered in the system. The property bag implementation is adjusted to always look at the local _Module variable first for "internal" class factories corresponding to C++ objects disguised as COM objects for persistence purposes only.

If you want to use an altogether different creation mechanism for your persistable objects, the IPropertyBag2 interface offers a method LoadObject(). It allows you to load a persisted state in an instance already created, as in Example 130.

Example 130: Loading a persisted state in an existing instance

14.3.1 MVC Integration

Usually, when your application uses the Model-View-Controller architecture, the model is the place from where the data you want to persist is accessible. You should save a model instance to a disk file as a response to the Save or Save as command, and you should retrieve an existing model from a disk file when your application receives the Open command.

In order to facilitate this typical scenario, SFL includes a class that merges the Model concept from the MVC architecture with the persistence capabilities of the property bags implementation.

The CMvcPersistableModel class is defined in the header file MvcPersist.h, located in the include\foundation\mvc folder of your SFL installation. This class defines only two virtual methods: Load() and Save(), both of which receive, as their only parameter, a string that represents the name of the file to which the disk operation will be directed. Both methods are declared as abstract, and no implementation is given.

Model objects derived from CMvcPersistableModel can Load() and Save() themselves to disk, but there is no assumption on how this process is actually going to be accomplished. The CMvcPropertyBagPersistableModel translates that abstract defined behavior to an actual implementation that uses SFL's XML property bag as the output of the Save() operation and input of the Load() process.

The CMvcPropertyBagPersistableModel offers the following services:

Model classes incorporating persistence in this fashion must include CMvcPropertyBagPersistableModel among their base classes and override two methods: WriteToPropertyBag() and ReadFromPropertyBag(). Both of these methods receive a pointer to an IPropertyBag interface, which will be used for all the input/output operations of the model. Both methods return a boolean value, which should be set to FALSE to indicate the occurrence of some error condition (TRUE otherwise).

Example 131 shows how to override these methods.

Example 131: Overriding read and write methods to enable persistence

It is important to notice that the IUnknown implementation provided in CMvcPropertyBagPersistableModel makes no assumption about the allocation of the model. The instance is not destroyed when the reference counter is decremented past zero, since there is no assurance the model is allocated on the heap. You can manage the lifetime of your model independently of this IUnknown implementation, or you can take advantage of reference counting for lifetime management by overriding Release() and performing the necessary deallocation process there.



Previous fileTop of DocumentContentsNo linkNext file

Copyright © Rogue Wave Software, Inc. All Rights Reserved.

The Rogue Wave name and logo, and Stingray, are registered trademarks of Rogue Wave Software. All other trademarks are the property of their respective owners.
Provide feedback to Rogue Wave about its documentation.