7

We have a scenario where we need to make assignments to fields using the method put(String, Object)

Ref: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_sobject.htm#apex_System_SObject_put

Once in a managed package the assignment:

String oldDesc = (String)acc.put('Custom_Field__c', 'some value');

will fail, because the packaged field will have a namespace prefix. So if it's been packaged as

`mypackage`

, the correct put() call would be:

String oldDesc = (String)acc.put('mypackage__Custom_Field__c', 'some value');

How can I avoid hard coding a package namespace?

3 Answers 3

5

I can suggest getting the namespace from the current class name..

public String getNamespacePrefix() {
    String namespacePrefix;
    String[] classNameParts = String.valueOf(<Enter className>.class).split('\\.', 2);
    if(classNameParts.size() > 1) {
        Type classType = Type.forName(classNameParts[0], classNameParts[1]);
        if(classType == <Enter className>.class) {
            namespacePrefix = classNameParts[0];
        } else {
            namespacePrefix = '';
        }
    } else {
        //If there is only one part, the class has no namespace
        namespacePrefix = '';
    }
    return namespacePrefix; 
}
11
  • 2
    If you're going to call this method frequently, it might be worth making it static, putting it in a utility class, and having it cache the result for subsequent calls.
    – Mr. DOS
    Commented Jun 4, 2015 at 17:09
  • 1
    Yes, I agree. This is just an example. If you are going to use this, do as Mr.DOS has suggested.
    – navD87
    Commented Jun 4, 2015 at 17:12
  • 1
    @bananka If I'm going to put the method in a utility class anyway, I'd add a static field to that class (private static String namespacePrefix = null;). At the top of the getNamespacePrefix() method, I'd check to see if that field was non-null, and if so, I'd return it. Otherwise, I'd go through the process of determining the namespace prefix, but right before returning, I'd set the value of the static field.
    – Mr. DOS
    Commented Jun 5, 2015 at 14:55
  • 2
    @bananka I've written an example of this pattern. Hopefully this will clear up what I'm suggesting.
    – Mr. DOS
    Commented Jun 5, 2015 at 17:44
  • 1
    @Mr.DOS thanks for the sample. This cache is only alive until the page is closed and the apex transaction ends, isn't it? I guess it could be more useful in java or c#.
    – user39399
    Commented Jun 8, 2015 at 11:29
5

If the logic is in a class known to not be an inner class then the logic can be simpler:

public class Utils {
    // Return the namespace prefix or an empty string if there isn't one
    public static String namespacePrefix {
        get {
            if (namespacePrefix == null) {
                String[] parts = String.valueOf(Utils.class).split('\\.', 2);
                namespacePrefix = parts.size() == 2 ? parts[0] : '';
            }
            return namespacePrefix;
        }
        private set;
    }
}
2
  • This doesn't work. I run it in execute anonymous and get Error: Invalid type: [classFromMyPackage] Commented Jun 21, 2021 at 13:19
  • @AndriiMuzychuk As that type name isn't part of the code I posted, that error is not evidence that the posted code does not work.
    – Keith C
    Commented Jun 21, 2021 at 16:47
4

Can you not try like this without doing any extra efforts? If you know any custom field or custom object of your managed package then the following solution should work.

If you have a custom object with Custom_Object__c API Name

Schema.DescribeSObjectResult dsr = Custom_Object__c.sObjectType.getDescribe();
String namespacePrefix = dsr.getName().remove(dsr.getLocalName());

If you have a custom field with Custom_Field__c API Name

Schema.DescribeFieldResult dfr = Account.sObjectType.fields.Custom_Field__c.getDescribe();
String namespacePrefix = dfr.getName().remove(dfr.getLocalName());

I think this way you don't need to do any query on Apex class. Doing a query or using an apex class may lead you in a wrong path as there could be 2 managed packages with the same class name but there won't be a problem with 2 fields with the same API name since it will pick the managed package field.

1

You must log in to answer this question.

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