apex-enterprise-patterns / at4dx

Advanced Techniques for Salesforce DX Adoption Framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to handle platform objects in selectors? (groups, users,...)

simon-nowak opened this issue · comments

Hello,

I'm trying to convert my application that is using the fflib to the AT4DX framework (we are moving our architecture to unlocked packages). In the past we used the selectors to query data from:

  • groups
  • users
  • permission sets...

And I just can't use those objects in the ApplicationFactory_SelectorBinding. I was thinking to put them in our "core" package.

How this should be handle?

G'day @simon-nowak

If I understand your question correctly, you are trying to set up selectors for Groups, Users, PermissionSets, etc but there is no value in the BindingSObject__c field on the ApplicationFactory_SelectorBinding__mdt object available. That is because, while the BindingSObject__c field is the data type of MetadataRelationship, that does not list a lot of the core SObjects. We have spoken to Salesforce regarding this but the gap is not expected to be filled for sometime, if at all.

In the meantime, there is the BindingSObjectAlternate__c field which is to be used in these situations. You simply need to specify the SObject API name that you want to create a binding for. In these situations, you would leave the BindingSObject__c field empty.

All of the ApplicationFactories that rely on SObject bindings (i.e. SelectorBinding, DomainBinding, and UnitOfWorkBinding) have the "Alternate" binding field for SObjects that are not revealed from the primary MetadataRelationship binding SObject field.

I hope this helps. If I misunderstood your question, just let me know.

Hello @ImJohnMDaniel,

Really thank you for your fast answer. This is exactly what I asked for. I should have read more carefully the description of fields.

I have an additional question for those particular selectors. In which package would you recommend to put them? (we are adopting the architecture described here: https://www.youtube.com/watch?v=yw-QoE4l0p0 Seems really nice and powerfull)

From my understanding, the best place could be the "core" package. But maybe the "core" package should not contains SObject.

We have an org that have only 1 purpose. For now all our packages will depends on "common" (that is containing account). But i'm not feeling confortable to put those selectors in "common".

G'day @simon-nowak

IMO, the best practice is not to have a "core SObject" package. It is better to have more of a mix of various package types; framework layer packages, business layer packages, project or org common layer packages, 3rd party extension packages, as well as integration layer packages. I would suggest a talk that I gave last year at VirtualDreamin2020 entitled "Architectural Considerations to Implementing DX and 2nd Generation Packaging". That should give you some good ideas and strategies about how to approach what metadata should go to what package. I have used this approach successfully on at least a half dozen projects over the last year alone that I have design influence in. If you have more specific questions, feel free to let me know and we can figure out a time to discuss.

Hope this helps.

@simon-nowak, something else that might be helpful are a couple of "rules" that I have been curating when architecting 2GPs. Hopefully, they will be useful as well to you. Let me know if you have questions on these.

"Package Rules"

  • "An SObject is always ‘owned’ by one and only one package”
  • "An SObjectField is always ‘owned’ by one and only one package, but not necessarily the same package as the SObject"
  • "A package should have its own API name prefix"
  • "You can have multiple 'packageDirectories' in a repo BUT you only have one package per source code repo"
  • Picklists on org wide common SObjects should not be relied on nor added to.

Again, @ImJohnMDaniel the video was amazing. I think I didn't understood at first the purpose of the common layer:

My previous understanding:

  • 1 "common" for account,
  • 1 "sales" for opportunities with all our business logic (depends on "common")
  • 1 "service" for case (depends on "common")
  • several downstream package around case that depend on "service" (we have lot of business logic here)

But now I see:

  • 3 common package with almost nothing inside: account/opportunity/case
  • multiples small packages that will depend on the commons

Am I right?

Another question. I'm currently promoting as global a picklist inside account. I wanted this picklist to be shared by case/opportunity. But I was planning to let the picklist live inside account. It's a mistake no? If I want several common the picklist cannot stay here.

Where does it live?
Not inside the framework layer I guess.
And not inside our old un-happy soup project. If so it will be difficult to scratch orgs (we can figure out a way, but I don't like it).
--> or maybe we forget about this feature

I have 1000000 questions more. If there is a way to discuss I'm in.

G'day @simon-nowak. I would probably consider the potential of a single, org-wide common package and a project common package. They would contain selectors, domains, and other SObjects definition files common to two or more business layer packages.

Would love to catch to discuss more. I usually hang out on the Good Day, Sir! Slack Community and it is a good place to continue the discussion.

I'm closing this issue. Additional questions will go to https://www.gooddaysirpodcast.com/community