Apex Triggers

Trigger Framework

To address the following problems we need to use a trigger framework instead of cramming all logic inside triggers:

    1. It is very difficult to maintain and debug code that is not structured according to OOP principles
    2. We should create abstractions of common logic
    3. We should have one trigger per object
    4. It is not possible to deactivate triggers in Production (without doing a deployment from a sandbox)

The following framework makes use of an optional Custom Metadata Type called TriggerSetting that controls whether a trigger is active. See the sub-section entitled "Trigger Setting" for more.

/**
 *  Central trigger handler
 *  This class must be extended and implemented for all trigger handlers
 */
public virtual class TriggerHandler {
    protected virtual void onBeforeInsert() {}
    protected virtual void onBeforeUpdate() {}
    protected virtual void onBeforeDelete() {}
    protected virtual void onAfterInsert() {}
    protected virtual void onAfterUpdate() {}
    protected virtual void onAfterDelete() {}
    protected virtual void onAfterUndelete() {}
    
    /**
     *  Invokes the appropriate handler method based on the triggering event
     *  Skips the trigger if TriggerSettings has this trigger set to inactive
     */
    public void run() {
        if (!isTriggerActive()) return;
        
        if (Trigger.isBefore && Trigger.isInsert) onBeforeInsert();
        else if (Trigger.isBefore && Trigger.isUpdate) onBeforeUpdate();
        else if (Trigger.isBefore && Trigger.isDelete) onBeforeDelete();
        else if (Trigger.isAfter && Trigger.isInsert) onAfterInsert();
        else if (Trigger.isAfter && Trigger.isUpdate) onAfterUpdate();
        else if (Trigger.isAfter && Trigger.isDelete) onAfterDelete();
        else if (Trigger.isAfter && Trigger.isUndelete) onAfterUndelete();
    }
    
    private Boolean isTriggerActive() {
        // check TriggerSetting__mdt to see if the Active__c flag is set for this trigger
    }
}

To implement a handler for a trigger, extend the above class and implement any method that is needed, like so:

public class AccountTriggerHandler extends TriggerHandler {
    protected override void onBeforeUpdate() {
        // before-update logic
    }
}

The trigger would then be reduced to a single line, as follows:

trigger AccountTrigger on Account (
    before insert, before update, before delete, after insert, after update, after delete, after undelete) {
    new AccountTriggerHandler().run();
}

Trigger Setting

A standard configuration for this Custom Metadata Type can have the following fields:

      • Label: Object Trigger (e.g. Account Trigger)
      • Name: Object Name (e.g. Account)
      • Active__c: checkbox (default checked)
Post a Comment (0)
Previous Post Next Post