SObject Wrappers
Requirements of SObject wrappers
All SObjects must be wrapped so that interactions with SObjects are not directly exposed to external packages. This requires the creation of wrapper classes for every SObject that we need to access. There is a base wrapper class named WrapperBase,
which contains the getInstance
method and other helper methods. The getInstance
method will auto check the CMT (Custom Metadata Type) to see if there is an override, and it will instantiate based on that. When the getInstance
method is called, the SObject provided is auto-mapped to the wrapper class via the Reflection class. The auto-mapping will take the API name of the SObject, convert it camel case, and assign that to the value in the wrapper class. For example:
EventApi__Thumbnail_Image_Url__c -> thumbnailImageUrl
Here is a how wrapper class should be written:
/*
* -----------------------------------------------------------------------------
* COPYRIGHT (C) 2018, FONTEVA, INC.
* ALL RIGHTS RESERVED.
*
* ALL INFORMATION CONTAINED HEREIN IS, AND REMAINS THE PROPERTY OF FONTEVA
* INCORPORATED AND ITS SUPPLIERS, IF ANY. THE INTELLECTUAL AND TECHNICAL
* CONCEPTS CONTAINED HEREIN ARE PROPRIETARY TO FONTEVA INCORPORATED AND
* ITS SUPPLIERS AND MAY BE COVERED BY U.S. AND FOREIGN PATENTS, PATENTS IN
* PROCESS, AND ARE PROTECTED BY TRADE SECRET OR COPYRIGHT LAW. DISSEMINATION
* OF THIS INFORMATION OR REPRODUCTION OF THIS MATERIAL IS STRICTLY FORBIDDEN
* UNLESS PRIOR WRITTEN PERMISSION IS OBTAINED FROM FONTEVA, INC.
* -----------------------------------------------------------------------------
*/
/**
* Term wrapped object with camel case properties. Each properties maps to a field on the SObject that has _ for each
* capital letter. Ex. (isActive -> Is_Active__c)
*/
global virtual inherited sharing class Term extends WrapperBase {
@AuraEnabled
global Id id;
@AuraEnabled
global String name;
@AuraEnabled
global Boolean isActive;
@AuraEnabled
global Date termStartDate;
@AuraEnabled
global Date termEndDate;
@AuraEnabled
global Id subscription;
@AuraEnabled
global Id subscriptionPlan;
@AuraEnabled
global Id contact;
@AuraEnabled
global Id account;
@AuraEnabled
global Id item;
@AuraEnabled
global Decimal assignmentsAllowed;
@AuraEnabled
global Decimal activeAssignments;
@AuraEnabled
global Date nextScheduledPaymentDate;
@AuraEnabled
global Boolean cancellationRequested;
@AuraEnabled
global List<SubscriptionLine> subscriptionLines = new List<SubscriptionLine>();
@AuraEnabled
global List<Assignment> assignments = new List<Assignment>();
public static final String feature = 'Term';
/**
* Get base instance with no initial S0bject.
*
* @return Term
*/
global static Term getInstance() {
return (Term)getInstance(new OrderApi__Renewal__c());
}
/**
* Get base instance with list of initial SObjects.
*
* @param terms List<OrderApi__Renewal__c>
*
* @return List<Term>
*/
global static List<Term> getInstance(List<OrderApi__Renewal__c> terms) {
return (List<Term>)WrapperBase.getInstanceHelper(MembershipConfiguration.MODULE_NAME, feature,Term.class.getName(),terms);
}
/**
* Get base instance with an initial SObject.
*
* @param term OrderApi__Renewal__c
*
* @return Term
*/
global static Term getInstance(OrderApi__Renewal__c term) {
return (Term)WrapperBase.getInstanceHelper(MembershipConfiguration.MODULE_NAME, feature, Term.class.getName(), term);
}
/**
* Term Constructor that should not be called directly.
*/
global Term() {
}
public override void fromSObject(SObject termObj) {
}
public override SObject toSObject() {
super.toSObject();
this.subscriptionLines = new List<SubscriptionLine>();
this.assignments = new List<Assignment>();
return Reflect.mapTo(this,OrderApi__Renewal__c.class);
}
}
In the above code, the fromSObject
will be auto-called during instantiation. This method will be used to map anything that the auto-mapping cannot do.
Each wrapper class should have a private final variable-named feature. This string variable is used to power the dependency injection overrides via CMTs.