You can use EAL event methods on model classes to initialize, update, and archive model objects when they are created, saved, or deleted; this page is for MDriven Designer modelers who need automatic object-lifecycle behavior.
Use EAL to change model objects
OCL expressions are side-effect free: they calculate and navigate but do not assign values or otherwise change the model. A ViewModel expression is therefore OCL; it defines a projection of model data for a ViewModel and must not alter that data.
Use an EAL method when your expression must change an object. EAL uses assignments and operations such as Create to act on model objects. Typical places to use EAL are:
- Lifecycle event methods on a class, such as
OnCreateandOnUpdate. - Actions that a user executes.
- Other non-query methods that intentionally change model objects.
A class method marked IsQuery is an OCL query method. It is side-effect free and can be called from other OCL expressions. A method that changes objects must have IsQuery set to false.
Handle object lifecycle events
MDriven recognizes the following hard-coded method names when they are present on a class. Set IsQuery to false for all three methods.
| Method name | When it runs | Use it for | Important limit |
|---|---|---|---|
OnCreate
|
After a new object has been created. | Initial values, such as a creation timestamp or GUID. | Call self.base.OnCreate when the superclass implementation must also run.
|
OnUpdate
|
Immediately before the object is saved to the database. | Values that must be refreshed on every save, such as a change timestamp. | Do not create objects here. A newly created object from an OnUpdate action will be left unsaved.
|
OnDelete
|
When the object is deleted. | Recording deletion information in an archive class. | Keep only the information that must remain after the original object is gone. |
For the save lifecycle and save behavior, see Save. For details specific to each event, see OnCreate and OnUpdate.
Add lifecycle methods to a class
- In MDriven Designer, select the class that owns the attributes and behavior.
- Add a method named exactly
OnCreate,OnUpdate, orOnDelete, depending on the event you need. - Set the method's IsQuery setting to
false. - Enter the EAL expression in the method body.
- Save and test the relevant lifecycle operation: create an object, save a changed object, or delete an object.
The method names are significant. MDriven triggers OnCreate, OnUpdate, and OnDelete by these names when it finds them on the class.
Example: apply timestamps and a GUID
A common model hygiene pattern is to give each persistent business object:
CreateTimefor when it was created.ChangeTimefor when it was last saved.Guidfor a globally unique identifier that can be retained when data is exchanged with other systems.
For example, a class such as Order can use the following methods.
Initialize a new object
Add a non-query OnCreate method:
CreateTime:=DateTime.Now;
self.Guid.newGuid()This assigns the creation time and generates a new GUID for the new Order.
If the class inherits lifecycle behavior from a superclass, call the superclass implementation as needed:
self.base.OnCreateStamp each saved update
Add a non-query OnUpdate method:
if self.existing then -- This avoids touching the object if it has been deleted
self.ChangeTime:=DateTime.Now;
false
else
false
endifself.existing prevents the method from changing an object that has already been deleted. The final false is part of this event expression pattern.
Do not add DeletedObj.Create, or any other object creation, to OnUpdate. Objects created during OnUpdate are not saved.
Archive a deleted object's GUID
If your model has an archive class named DeletedObj with an attribute DeletedGuid, add a non-query OnDelete method:
let deleted = DeletedObj.Create in
(
deleted.DeletedGuid := self.Guid
)For example, deleting an Order with GUID ... creates a DeletedObj record that retains that GUID. An integration can then discover that the previously exported object no longer exists.
When many classes need the same timestamps, GUID, and deletion logging, place the attributes and lifecycle methods on a shared superclass. Set that superclass as the package's default superclass so new classes in the package inherit the behavior.
This avoids copying the same three methods to every business class. A new class, such as Customer, then receives CreateTime, ChangeTime, Guid, and the lifecycle behavior through inheritance. See Object Identity for the complete default-superclass pattern and its integration rationale.
Choose event methods or actions deliberately
Use lifecycle methods for rules that must run because an object changes, regardless of which user interface or process initiated the change. For example, ChangeTime belongs in OnUpdate because every save should update it.
Use an action for an operation a user chooses to perform. When the operation acts on one selected instance, a class action is usually appropriate: it becomes available where that class instance is shown. See Class actions for this usage pattern.
Do not put model-changing assignments in a ViewModel expression. For example, a ViewModel expression may calculate which orders to show, while an action or non-query class method changes an order's status.
Do not confuse lifecycle events with database change tracking
Lifecycle methods react to changes made through the MDriven model. They are not a way to discover direct updates made by another system against SQL Server tables. If an external system writes to the same database, use the separate SQL Server change tracking pattern to invalidate affected objects in MDrivenServer.
