Generic Apex Trigger

So I was kind of throwing round the idea of making a generic apex trigger that is callable by multiple objects. Say you have the following sObjects:

Account
Sales__c
Sales_Contacts__c

And I wanted to make a trigger that is called when any of those objects are updated – for example:

trigger autoTaskCreation on Account, Sales__c, Contacts (after insert, after update) {
    for (sObject s :Trigger.new) {
        AutoTaskCreation a = new AutoTaskCreation();
        a.createTask(s);
    }
}

and then on the controller side:

public with sharing class AutoTaskCreation {

    private integer _returnvalue;
    private string _objecttype;

    public void createTask(sObject s)
    {
        _objecttype = s.getSObjectType();
        if (_objecttype == Account )
        {
            _returnvalue = _createcccounttask();
        }
        else if(_objecttype == Sales__c)
        {
            _returnvalue = _createsalestask();
        }
        else
        {
            _returnvalue = _createsalessontacttask();
        }
    }
}

Has anyone done something similar to this/does apex reflection support generics in this way? Any help would be appreciated!

Answer

You’ve got the general idea from your answer. Dynamic Apex and Dynamic SOQL are the best way to reflect on SObject’s and as you’ve discovered you can determine the type easily. I would ensure however your method takes a list of SObject so it can implement bulkfication.

public void createTask(List<SObject> records)

You can use the List method getSObjectType to get the type of objects in the list. You will also need multiple triggers, but you can simplify each of them into a single line, like so.

trigger autoTaskCreation on Account (after insert, after update) {
    new AutoTaskCreation().createTasks(Trigger.new);
}

However you will not then know the event being handled from within the createTasks method. You can either pass this as an additional parameter or to make your Trigger even simpler and your method handle future events without modifying the signature. You could do something like this…

trigger autoTaskCreation on Account (after insert, after update) {
    AutoTaskCreation.handleTrigger();
}

Then define your AutoTaskCreation class something like this….

public class AutoTaskCreation
{
    private List<SObject> Records;

    public AutoTaskCreation(List<SObject> records)
    {
         this.Records = records;
    }

    public void onHandleAfterInsert()
    {
         SObjectType objectType = Records.getSObjectType();
    }

    public void onHandleBeforeInsert()
    {
         SObjectType objectType = Records.getSObjectType();
    }

    public static void handleTrigger()
    {
         // Create handler and delegate events to methods
         AutoTaskCreation taskCreation = new AutoTaskCreation(Trigger.new);
         if(Trigger.isBefore && Trigger.isInsert)
             taskCreation.onHandleBeforeInsert();
         else if(Trigger.isAfter && Trigger.isInsert)
             taskCreation.onHandleAfterInsert();
    }
}

More Advanced: If you wanted to get more sophisticated, instead of the if/else approach in the handlers, you could develop this idea out as an Apex base class. Extending from other classes and overriding base class methods to specialise for the specific objects you want to support. Implementing a factory pattern to register the derived classes for the triggerHandler method to instantiate via Type.newInstance automatically based on the object type.

Further Info: This is simpler example on a number of broader Trigger patterns I’ve seen, including one of my own. If you want to take a broader look at them, I’ve listed the ones I’m aware below, others may have their preferences. Most I’ve seen should allow you to map a single trigger handler class to an object, but none will workaround the need for a distinct trigger per object, the best we can do is minimise the logic in each trigger. Note that these do vary on features and overhead.

Attribution
Source : Link , Question Author : gfppaste , Answer Author : Community

Leave a Comment