I have a rather simple Trigger. When fired it determines its own type and calls an appropriate function in Trigger handler class.
trigger Project_Trigger on Acme_Project__c (before insert, after insert, before update) {
if (Trigger.isBefore) {
if (Trigger.isInsert) {
ProjectHandler.projectBeforeInsert(Trigger.new);
}
...
}
...
}
Trigger handler class takes Trigger.old/Trigger.new and performs all required logic.
public class ProjectHandler {
public static void projectBeforeInsert(List<Acme_Project__c> newProjects) {
...
}
}
I would like to make the handler class work for many different Custom Objects, not only for Acme_Projects__c. In fact I already have those Custom Objects and I can just clone the class and find/replace 'Acme' with, for instance, 'Some_Other_Client', but that seems too repetitive.
My idea is to create an intermediary Custom Object, like Clipboard_Project__c, and use it to populate with Trigger.old/Trigger.new values, perform class handler methods on instances of that Custom Object, and then return everything back to trigger to do final DML operations…
In the Trigger –
Clipboard_Project__c[] newProjects;
for (Acme_Project__c p : Trigger.new) {
Clipboard_Project__c one = new Clipboard_Project__c(
Id = p.Id,
Field_1__c = p.Field_1__c,
...);
newProjects.add(one);
}
ProjectHandler.projectBeforeInsert(newProjects);
//some code that puts newProjects back into Trigger.new
delete(newProjects);
Is this a viable approach? How do I put newProject contents back into Trigger.new (as far as I understand that's the only way to make Custom Object instances update)?
Best Answer
Apex has support for generic sObjects. You can do pretty much anything with a generic sobject that you could do with a specific sObject type (get/set fields, dml operations, etc.) So you could write your generic handler as follows:
There is no reason to pass anything back to the triggers as you can perform everything in the trigger handler. The best practice is to have a simple trigger that delegates all the actual work to a trigger handler. If you have slightly different logic for the different types of sObjects: