🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Seeing everything that is persisted
This page was created by Alexandra on 2018-11-28. Last edited by Wikiadmin on 2026-07-29.

You can intercept modeled objects as they are read from and written to persistence by adding a custom handler derived from ChainedPersistenceHandlerBase; this is for developers who need cross-cutting persistence behavior such as update tracking.

What this extension point does

Persistence keeps modeled objects available after an application session ends. MDriven uses persistence mappers to translate modeled objects to and from their storage representation; see Documentation:Persistence mappers.

ChainedPersistenceHandlerBase is a base class for a custom persistence handler that sits in front of the existing persistence handler. Your handler can inspect or change the objects that pass through it when data is persisted or retrieved, while the handler already configured for the EcoSpace continues to perform the underlying persistence work.

This is useful when the same rule must apply across many modeled classes and should not be repeated in every ViewModel or operation.

When to use it

Use a chained persistence handler for behavior that concerns all, or a clearly defined group of, persisted objects.

Requirement Appropriate use Example
Record when an object is updated Inspect objects being persisted and update shared tracking data. A common model base class implements ITrackUpdate. When a changed object implements that interface, set its update date and time before it is stored.
Observe persistence activity Inspect objects going to or coming from persistence. Identify which tracked business objects are being loaded during a diagnostic session.
Class-specific business behavior Prefer model rules, operations, or a focused implementation rather than a global handler. A rule that applies only when a House enters a particular state belongs with that business behavior, not in a handler that sees every persisted object.

Configure the handler before the EcoSpace becomes active

Install the custom handler in the EcoSpace before the EcoSpace is activated. The order is important: the custom handler must be chained before the current persistence handler, not replace it.

  1. Create a class that inherits from ChainedPersistenceHandlerBase.
  2. Override the persistence callbacks needed for your scenario. Use the callbacks that handle objects going to persistence, coming from persistence, or both.
  3. In each override, apply your rule only to the objects it concerns.
  4. Chain the custom handler in front of the EcoSpace's current PersistenceHandler.
  5. Complete this setup before the EcoSpace goes active.
  6. Verify that the original persistence mapper still saves and reloads data.

Do not discard or bypass the existing handler when installing the chain. The existing handler is the component that performs the configured persistence work.

Example: maintain an update timestamp

A common pattern is to define a shared base class for persisted business classes and let that base class implement an interface such as ITrackUpdate. The interface represents the fact that an object has update-tracking data.

For example, a Customer and an Order may both inherit from the shared base class. When either object is changed and persisted, the chained handler recognizes the interface and sets its update date and time. Classes that do not implement the interface are left unchanged.

The rule in the handler should follow this sequence:

  1. Receive the object in the callback that runs before it is persisted.
  2. Test whether the object implements ITrackUpdate.
  3. If it does, set the tracking date and time.
  4. Continue the chain so that the existing persistence handler performs the actual save.

Keep the tracking rule narrow. For example, decide explicitly whether creating a new object should set the same field as updating an existing object, and avoid changing objects that are only being read.

Verify the configuration

Test the handler with a persisted environment.

  1. Start with a model that uses a persistence mapper.
  2. Create an object that implements the tracking interface and save it.
  3. Change the object and save again.
  4. Reload or re-read the persisted object.
  5. Confirm that the expected tracking value was stored and that the object can still be loaded.
  6. Repeat with an object that does not implement the interface and confirm that the handler does not apply the tracking rule to it.

The System Prototyper and Debugger can be used to create objects, save changes, and re-read persisted data while you verify the behavior. In a persisted environment, the Debugger exposes save, undo, redo, and cancel actions for unsaved changes.

Design considerations

  • A persistence handler sees technical persistence flow. Do not use it as a replacement for business rules that belong in the model.
  • Keep handler work small and predictable. It runs as part of persistence for every object within its scope.
  • Test both directions of the chain when you intercept reads as well as writes.
  • Keep the current persistence handler in the chain. MDriven persistence mappers handle the translation between modeled objects and the configured storage mechanism.
  • If you need custom persistence mapping rather than interception around an existing mapper, see Documentation:Working with Code and Persistence Mapping.

See also