The article is prepared by our developer Aliaksei Vishavaty.
In Salesforce development, managing the order of execution for trigger handlers is crucial –especially in complex orgs with a branched business logic – to ensure data integrity and avoid conflicts. In this article, we'll explore how to leverage custom metadata to implement the desired order of execution for trigger handlers in Salesforce.
Understanding the challenge
When dealing with multiple trigger handlers in Salesforce, it becomes challenging to control the order of execution. This is a complex problem because Salesforce does not provide an out of the box solution to order handlers for each object. For example, suppose you have an "Account" object trigger that invokes multiple handlers, such as “AccountValidationHandler" and "AccountDataSendingHandler." Depending on the business requirements, you may need to execute the validation logic before sending the account record. Without explicit control, the execution order may vary, leading to unexpected results (e.g. sending account data to the third party service before the record is validated) or data inconsistencies.
Introducing custom metadata
One of solutions to address the challenge is a Salesforce custom metadata – a powerful feature that allows developers to define specific configurations and settings. Unlike custom objects or settings, this metadata can be deployed and queried programmatically. Also, in our case, custom metadata querying will not count against the Salesforce limits. This means that utilizing custom metadata for querying and storing information does not consume any of the allocation or usage limits set by Salesforce. This can be a significant advantage, especially in complex systems where the limits can quickly be reached. Other than that it becomes easier to activate/deactivate trigger handlers using metadata without having to deploy the main handler. So this feature provides flexibility and customization options, making it an ideal choice for defining the execution order of trigger handlers.
Setting up custom metadata type
To begin, create a custom metadata type to represent trigger handlers. Let's call it "TriggerHandlerMetadata." Include the following fields:
1. Handler Name (Text): Represents the name of the trigger handler.
2. Order Number (Number): Determines the execution sequence of the trigger handler.
3. SObject (Picklist): Lists all involved objects’ API names
4. Active (Boolean): Indicates if the handler is active
Creating custom metadata records
Create custom metadata records for each trigger handler. For example, let's create two records:
Record 1:
- Handler Name: AccountValidationHandler
- Order Number: 1
- SObject: Account
- Active: true
Record 2:
- Handler Name: AccountDataSendingHandler
- Order Number: 2
- SObject: Account
- Active: true
Specify unique handler names and assign order numbers to indicate the desired execution sequence. In this example, AccountValidationHandler should execute before AccountDataSendingHandler.
Modify the trigger Handler Factory
The HandlerFactory in our implementation is used to instantiate and execute Trigger Handlers associated with sObjects.
The HandlerRegistry class is used to collect all handlers for each triggered sObject by iterating over the sorted custom metadata records and creating instances of trigger handlers based on the Handler Name field. Handlers instances are stored in a sorted list for later execution.
The IHandler represents a simple interface that contains all possible methods that can be used in the trigger handler. This interface is used in every created trigger handler in order to design the polymorphism principle.
Modifying the Apex trigger
Now, let's modify the relevant Apex trigger to incorporate the custom metadata-based execution order. The only thing needed is to pass the SObject type to the createHandler method for getting all trigger handlers to be executed to the specific sObject (for Account in our case).
Now, let's modify the relevant Apex trigger to incorporate the custom metadata-based execution order. The only thing needed is to pass the SObject type to the createHandler method for getting all trigger handlers to be executed to the specific sObject (for Account in our case).
Modifying the Apex trigger handler
In order to stick to our implementation, the trigger handler should implement and override the specific methods from the IHandler interface that should be used in the class.
To keep the bulkification all triggered records that suit specific conditions can be stored in the list and then used in the andFinally() method.
Conclusion
Implementing the order of execution for trigger handlers in Salesforce using custom metadata provides developers with control and flexibility. By defining the execution sequence through custom metadata records, you can optimize automation processes and maintain consistent data processing. Apply this technique in your Salesforce development projects to enhance efficiency and maintain a structured codebase.