Changing class dynamically
The Enterprise layer is free to define rules applied to ORG, Work-Cover-, or Work- that reference ORG-Data- classes. Application layer ORG-APP-Work classes are also free to reference ORG-Data- classes. The Application layer’s ORG-APP-Work classes can also reference ORG-App-Data classes.
Suppose a data class is sharable between sibling applications. In that case, because it is significant to the enterprise, it makes sense to define the sharable portion as an ORG-Data class. Each sibling application is free to extend that Enterprise layer Data class to suit its specific needs.
Enterprise layer code, which is extendable to the Application layer, can leverage the fact that Enterprise layer data classes can be extended to higher layers.
OOTB change class example
Pega uses px, py, and pz as prefixes for its properties.
The px prefix generally means a property's value should remain the same once its value is set. Examples include pxCreateDateTime and pxCreateOperator which record historical information. Something can only be created once by whomever it was that created it.
When deciding what prefix to use for the property representing a rule's Apply-to class, Pega uses the px prefix. However, Pega for instance during transfer assignment changes the value of pxObjClass at runtime from Assign-WorkBasket to Assign-Worklist and vice-a-versa using Page-Change-Class method.
The Page-Change-Class activity method has a keep parameter. Ignoring the more complex third option with the value of 2, the remaining keep parameter values are:
- 0 = the value of any property already present remains the same
- 1 = the value of any property already present will be overwritten by the data transform
The takeaway from this is that pxObjClass can be changed at runtime, but you must carefully perform that change.
For instance, You don’t have to configure a decision table to return a class name and alter the pxObjClass but you should try and build the class name using pattern inheritance appended by the specialization type. However, This may not be possible when you like to change the class from work to data.
Dynamic Class Referencing (DCR) is a pattern that has been used in Pega when the value for an object's pxObjClass is decided at runtime as opposed to design time.
Instantiate pages of different class using reusable code
Normally, a Lookup data page with a single key, such as pyGUID, uses a single pyGUID parameter. The D_Location Data Page, however, has a second Type parameter. The D_Location data page sources a LoadLocationDCR activity that utilizes the Type parameter as follows:
When parameter Type !="" continue processing. Otherwise, jump to step GO.
Set param.ObjClassNew = "FSG-Data-" + param.Type
Call PageChangeClass passing the primary page as the primary page.
Open an instance of FSG-Data-Location (Location) onto LocationTEMP
passing param.OpenClass as Primary.pxObjClass
using param,pyGUID the value for the class key, .pyGUID
Copy LocationTEMP to Primary
Remove LocationTEMP from memory
This Type parameter tells Pega to create a LocationTEMP page based on the value of Primary.pxObjClass after it was changed. Regardless of the derived class, Pega accesses the row in the Location database table that matches the supplied pyGUID. Pega does not just return the properties defined by FSG-Data-Location. Instead, Pega returns all of the properties in the Location table associated with the derived Location class. The original D_Location page was defined in FSG-Data-Location class but by changing the class name we can pull ParkingLocation instance data and also ensure to have the changed class as pxObjClas on the data page.
This activity shows that reusable code can be written to instantiate pages with different classes. Classes generated on-the-fly NOT read from the database table. There is no pxObjClass column in the Customer Data schema.
The class of the data page could be changed based on the type parameter, thus ensuring one single data page is created which can used for any classes.
Dynamic Class Reference Example
Use DCR against a class with a clearly defined type instead of a class that does not, such as ORG, ORG-App, [*]-Data, and [*]-Work. Within the mission-provided solution code, there are two related sample applications: FSGSample and FSGSample2. Two similar case types are defined in each sample application: Roadside Assist and Service Complaint.
These four case types utilize and extend the same generic Data type: FSG-Sample-Data-Vehicle. The following image shows three specializations of *-Data-Vehicle within each layer, the specializations being -Car, -Truck, and -Motorcycle.
A common way to use DCR is to define an application-wide data type with a property for every value (for example, .MotorCycleClass). A data page, typically named D_AppExtension, is defined within this application-wide data type. That Data Page sources a Data Transform to populate the data page's property values. A value is retrieved using syntax such as D_AppExtension.MotorCycleClass. Layers above the layer that defined the application-wide Data type would override that data transform from the AppExtension data page. Note that this approach does not adhere to the Open/Closed Principle. Whenever a new derived class is defined, a new property must be added to the AppExtension data type.
The modular way to use DCR within a class hierarchy is to define a DCR data page at the base of that class hierarchy. Within the provided solution, the FSG-Sample-Data-Vehicle class defines a D_VehicleDCR Data Page. This data page's sole purpose is to set its pxObjClass based on the value of the Data Page's required Type parameter. It does this by sourcing a data transform named LoadVehicleDCR.
The code in FSGSample does not actually use D_VehicleDCR. The code can call the LoadVehicleDCR Data Transform directly. It does this within the Service Complaint case’s Create stage. The FSG-Sample-Data-Vehicle IdentifyVehicle Section has an autocomplete control that sets the Vehicle's .Type property. On change, the section is refreshed. Before the refresh, the LoadVehicleDCR Data Transform is invoked. The .Type property supplies the value for the Type parameter. PageChangeClass activity is triggered to change the class as per the type property.
The primary goal of the two Vehicle sample cases is to show that the polymorphic classes defined in two different layers can be persisted and recovered from the same CustomerData schema database table —a table that lacks pzInsKey and pxObjClass columns.