0

So, I retrieved the namespace of the managed package since I know name of the class. But the question is how can I call the method of the managed apex class. Since the namespace returned is of type string, I am getting the error as class not defined.

    public static void callUpdateContract(List<String> dealSupportId) {
    try {
        ApexClass apx= [SELECT NameSpacePrefix FROM ApexClass WHERE Name = 'ContractServiceResource'];
        if(apx.NameSpacePrefix!=null || apx.NameSpacePrefix!='') {
            String res = apx.NameSpacePrefix.ContractServiceResource.updateContract('id');
        }
        
    }
    catch(Exception e) {
        
    }
}

Getting the error "Variable does not exist: ContractServiceResource".

2 Answers 2

1

Unless the managed package class implements Salesforce's nasty** Callable interface you cannot do anything dynamic with the managed package class other than use the Type methods, including Type.newInstance (and that assumes there's a default constructor available for use).

Everything else must be static as mentioned by @metasync.

You could isolate the static invocations within some form of "adapter" class you provide if entirely essential. This would isolate the specific static uses from most of your own code.

If you are doing this to remove an installation/deployment dependency on that managed package for your code, you're out of luck. However, if you are developing a package yourself, you could ensure that your "adapter" API is an interface or abstract class and have the implementation of this that calls through to this other managed package class outside your package and thus installed on/deployed to the org separately compared with your package. Your package would need to instantiate this implementation from a string of the implementation's class name via Type.forName(...).newInstance(). This approach is called Dependency Injection, where the dependency is separated out to configuration.

**: This Callable interface is a "quick hack" in Salesforce to introduce a common API that can be used for arbitrary method invocations, rather than providing effective Reflection capabilities in the language similar to those available in Java.

It is nasty because:

  1. There is no method discovery. You cannot discover which methods are supported, what parameters they take and what types they return.
  2. There is no type safety.

As an ISV product architect I would not want to touch this API if I can avoid it.

2
  • ** instead of "nasty" I would term this as "better than nothing". But I agree the lack of reflection is sad.
    – Keith C
    Mar 4, 2022 at 8:55
  • Personally I prefer the "nothing" approach :D
    – Phil W
    Mar 4, 2022 at 8:57
0

You need to call that class statically. For ex., if that namespace is 'abc', then you would call the function as abc__ContractServiceResource.updateContract('id')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.