🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Statemachines forcing your hand even if you are admin
This page was created by Wikiadmin on 2023-12-20. Last edited by Wikiadmin on 2026-07-29.

You can correct an object that is stuck in an incorrect state by using stateMachineForceMode for one controlled state-attribute write; this is for developers and administrators handling exceptional data correction.

Use force mode only to correct exceptional data

A StateMachine restricts a state attribute to the states and transitions defined for its class. Guards can also prevent a transition until the required business conditions are met. This protects the business flow: an object cannot normally move directly from State1 to State3 when the model requires it to pass through State2.

Sometimes an object is in the wrong state because the model was changed, a defect was found, or business data was interpreted incorrectly. If no legal transition can reach the correct state, use stateMachineForceMode to make one direct correction through the framework.

For example, an object was accidentally set to Discarded, but it must be restored to an active state. If the current model has no transition that can revive it, force mode can set the state attribute to the intended state without editing the database directly.

Do not use force mode as part of the normal business process. Model the required transition and its guards instead. Use stateMachineTrigger when you want the state machine to evaluate its normal guards and make an allowed transition.

Why not update the database directly?

Direct database updates bypass the MDriven framework. In particular, an external database change is not recorded in the MDrivenServerSynk table, so it will not propagate to MDrivenServer Slave configurations. It also will not be recorded with a timestamp in a HistorySlave configuration.

Force the correction through the framework instead, so the change follows the framework's handling of the object.

Force one state-attribute write

Call stateMachineForceMode immediately before assigning the state attribute.

self.stateMachineForceMode('State');
self.State := 'State3'

The parameter is the name of the state attribute, such as 'State'. It is not the name of the state you want to enter. The assignment value, 'State3' in this example, is the target state value.

See stateMachineForceMode for the operator definition and state-value details.

One-write limit

Force mode grants one free write only. After that write, normal state-machine rules apply again.

The following fails on the second assignment because the force authorization has already been consumed:

self.stateMachineForceMode('State');
self.State := 'State3';
self.State := 'State3'

If you must force two separate writes, call force mode before each one:

self.stateMachineForceMode('State');
self.State := 'State3';
self.stateMachineForceMode('State');
self.State := 'State3'

Force a state from C# code

If your code needs to perform an exceptional correction, execute the force-mode operation and the state assignment as separate ActionLanguage executions. The following example shows a method that accepts close or open and forces the TheStateAttribute attribute to that value.

public void StateMachineForce(string NewState)
{
    string ForceMode = "self.stateMachineForceMode('TheStateAttribute')";
    string close = "self.TheStateAttribute :='close'";
    string open =  "self.TheStateAttribute='open'";
    Eco.Handles.DefaultEcoSpace es = this.AsIObject().ServiceProvider().GetEcoService<IEcoSpaceService>() as Eco.Handles.DefaultEcoSpace;
    switch (NewState)
    {
        case "close":
            es.ActionLanguage.Execute(this, ForceMode);
            es.ActionLanguage.Execute(this, close);
            break;
        case "open":
            es.ActionLanguage.Execute(this, ForceMode);
            es.ActionLanguage.Execute(this, open);
            break;
        default:
            break;
    }
}

Adapt TheStateAttribute, close, and open to the state attribute and state values in your model. Execute force mode again for every state write that must bypass normal transition rules.

Design the normal flow instead

Use a StateMachine to describe the allowed state values, transitions, triggers, and guards. For example, a House can move from Plan to Construction through a StartConstruction trigger, while a guard can require that an address has been entered before the transition is allowed. Learn how to define that flow in OCL Editor, system prototyper and ViewModel.

If state changes are business-significant, implement OnStateChange for audit or logging. Do not use it to stop a transition; use guards for that purpose.

See also