1

This answer: Managed Package Integration without Extensions or Dependencies is now 4 years old and I was curious if it is still the only way to accomplish the following goal:

  1. Main Package
  2. Extension Package - May or May Not be installed along with the main package
  3. In main package need to determine if Extension is installed
  4. If installed run method in extension package passing in parameters
  5. No dependency can be created as the extension is not required but if present it must run at a specified point

So basically need to check if extension is installed and if so run a parameterized method without creating dependencies.

System.Type does not allow for the execution of methods or the passing of parameters AFAIK. I do not see any other way to accomplish this.

Granted, the previous answer is still applicable and does not consume much CPU time at all. Just curious if it is still the only and preferred way of doing this.

In the simplest form the following is what I currently have:

Main Package (Batch Apex)

System.Type apiMethod = Type.forName('ns', 'Class.Method');
If(apiMethod != null){
  Object apiCall = JSON.deserialize(
          '{"param1":null,"param2":"12345"}',
          apiMethod
  );
}

Extension Package

global class{
        global Id param1 {get;set;}
        global string param2 {get;set;}

        global method(){
            if(string.isBlank(param2) || param1 == null)
                throw new ex_Exception('Invalid Parameters');

            secondMethod(param1,param2);
        }
    }

    global static void secondMethod(Id param1, String param2) {
       ..Do something...
    }


}

Please ignore naming conventions as for illustration only. This works and does not create a dependency in either package.

9
  • You could create an interface in the main package which is then implemented in the extension package? Then you would just use Type.forName to see if the implementation is valid. With an interface, you wouldn't have to shove all the logic into a constructor but could rather have some methods to work with.
    – Adrian Larson
    Commented Aug 7, 2017 at 19:28
  • @AdrianLarson - The method needs to be executed from the main package (calling the extension package) not from the extension package. Interface confuse the hell out of me but I do not think this is possible with an interface. Am I wrong? Let me update the question with a most basic example of what I have, maybe that will help
    – Eric
    Commented Aug 7, 2017 at 19:30
  • I mean it would just be Type implementation = Type.forName('ImplementingClass'); if (implementation != null) { Interface instance = (Interface)implementation.newInstance(); instance.doStuff(); } You should be able to call that from the main package I would think.
    – Adrian Larson
    Commented Aug 7, 2017 at 19:32
  • @AdrianLarson - Not sure that is possible. The interface would have to be in the extension and thus create a dependency....Again. Interfaces confuse me so I may be wrong but I cannot wrap my head around a way to have an interface in a main package execute a method in an extension without creating a dependency
    – Eric
    Commented Aug 7, 2017 at 19:34
  • No you would define the interface in your main class. The extension is dependent on the main package, no?
    – Adrian Larson
    Commented Aug 7, 2017 at 19:34

1 Answer 1

2

You would use an Interface. In the base package, declare your interfaces as global, so they can be accessed in the extension package. Then, you can use Type.forName as usual.

Base Package

global interface DoSomething {
    void doSomething(Object param1, object param2);
}

...

Type externalType = Type.forName('ExtensionClass','extns');
if(externalType != null) {
    DoSomething data = (DoSomething)externalType.newInstance();
    data.doSomething(param1, param2);
}

Extension Package

global class ExtensionClass implements basens.DoSomething {
    global void doSomething(Object param1, Object param2) {
        // Do stuff here
    }
}
6
  • Ahh. The key is to check the extension namespace for a valid reference to the main interface? What if multiple classes in the extension implement the interface?
    – Eric
    Commented Aug 7, 2017 at 19:41
  • Does this add any benefit over the JSON deserialization? It adds an interface that is now exposable to customers which may not be a bad thing but would prefer to not have that. Additionally it cannot be modified once created and create a dependency in the extension which is currently not present. The joys of SF I guess
    – Eric
    Commented Aug 7, 2017 at 19:46
  • @Eric Unfortunately, by design, the interfaces have to be global. You can "hide" the actual logic inside public static methods in your extension, so they would only see the main method call(s). As for JSON, the serialization/deserialization process is *expensive.* Avoid it if at all possible. And yes, methods in an interface can never be modified, but they can be deprecated if you need to. Since a third package is involved, you could also build a parameter class to provide common data structures.
    – sfdcfox
    Commented Aug 7, 2017 at 19:49
  • Thanks. Third package is out of our control (not ours). Lots to think about. For this specific use case the deserialization takes < 1ms since it is only used to set parameters and execute another process.
    – Eric
    Commented Aug 7, 2017 at 19:59
  • Apologies, still confused on the naming. If my extension package implements BASENS.INTERFACE then how do I check while inside a base method for the instance of BASENS.INTERFACE in the extension package (the class in the extension that implements the base interface) using type.forname?? It cannot be EXTNS.BASENS.INTERFACE can it?
    – Eric
    Commented Aug 7, 2017 at 23:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .