Inside Catalio - Articles on Sales, Marketing, Support and Salesforce

If you have been coding in Salesforce for any amount of time, you will quickly realize that you have strict governor limits. Three months into my new position and I was tasked with consolidating all of the Case Triggers. We were getting SOQL Limits when trying to validate, and a total of 13 triggers.

It didn’t take long to find bloggers and even our Salesforce representatives talk about consolidating all the triggers into one Trigger. I decided to try and use the Factory pattern, a pattern I picked up at my previous job.

Even better, I found a great template, Force.com Recipe, talking about how to do this in Apex! I won’t explain all the details, since they do a very good job of that already, but I wanted to make my own little additions.

If you don’t care about an explanation, you can find my additions here.

Reflection(ish)

private static ITrigger getHandler(Schema.sObjectType soType)
{
    try {
        return (ITrigger)Type
              .forName(soType.getDescribe().getName() 
              + 'TriggerHandler').newInstance();
    } catch(Exception e) {
        throw new TriggerException('No Trigger Handler registered for Object Type: ' + soType);
    }
}

So I really didn’t like the idea of having to come and register a new TriggerHandler. I knew that some developers would forget this :). So I looked for a way to do this with reflection, but the closest I got was taking the SObject Type, converting it to a string, concatenating that with "TriggerHandler". So this works for us since we all know about the naming convention, and now we don't need to update this file every time we create a Trigger Handler.

Unique Sequence

private static String generateGUID()
{
    Blob b = Crypto.GenerateAESKey(128);
    String h = EncodingUtil.ConvertTohex(b);
    return h.SubString(0,8)+ '-' + h.SubString(8,12) + '-' + h.SubString(12,16) + '-' + h.SubString(16,20) + '-' + h.substring(20);
}

After debugging for awhile, I really missed having a way to see only the order of the events I cared about. So to fix this, I generated a unique number (Resembles a GUID — No built-in GUID in Apex????) that comes in handy when looking at your debug logs. Nothing crazy here.

Recursive Check

private static Boolean isFirstRun(Schema.sObjectType soType) {
    if(!recursions.containsKey(soType)) {
        recursions.put(soType, true);
        return true;
    }

    return false;
  }
}

I know, I know…I didn’t want to add this but I haven’t had enough time to go through and check every class that the TriggerHandler calls, but there seems to be a rogue class that causes a Recursive call sometimes. I thought it would be a good safeguard for the future. Super simple, just stores the SObject Type and a flag. If the Map contains the object type, then it’s already run, and we can safely skip the execute method.

if (isFirstRun(soTYpe)) {
  System.DEBUG('[TF | ' + soType + '] - ' + executionId + ': Executing... ');
  execute(handler, soType);
} else {
    System.DEBUG('[TF | ' + soType + '] - ' + executionId + ': Not Excuting (Recursive call)...');
}

I don’t think this is perfect and would love feedback, so let me know what your Trigger Factory looks like or how to improve mine!

You've successfully subscribed to Blog - Catalio
Welcome back! You've successfully signed in.
Great! You've successfully signed up.
Your link has expired
Success! Your account is fully activated, you now have access to all content.