Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Selector Layer / question about injecting method or criterias #71

Open
alanjaouen opened this issue Jan 24, 2023 · 4 comments
Open

Selector Layer / question about injecting method or criterias #71

alanjaouen opened this issue Jan 24, 2023 · 4 comments

Comments

@alanjaouen
Copy link
Contributor

Hi @ImJohnMDaniel @stohn777 ,

I'm starting to implement AT4DX in my company, and this framework help us a lot for switching to unlocked package, so first of all thank you for sharing this with us.

I'm wondering about a use case for splitting my monolithic code in package:

Let's says that:

  • PackageA define AccountSelector
  • PackageB define a field packageB_id__c on Account

I would like to define in packageB a methode like AccountSelector.getAccountByPackageB_id__c(Set<String>)

I did not find any exemple about this use case, should I create an AccountSelector specifically for PackageB?

Thanks for your time,

Best
Alan

@ImJohnMDaniel
Copy link
Collaborator

G'day @alanjaouen. Thanks for reaching out.

A couple of questions for you

  • Have you seen the various videos about using the AT4DX framework as well as the VirtualDreamin2020 talk - "Architectural Considerations to Implementing DX and 2nd Generation Packaging"?
  • Would PackageA be placed in a "business layer" package or in a "common layer" package?

Based on what I have heard you describe, it sounds like a good candidate for the AT4DX feature "Selector Method Injection", but let me know the answers to questions above and we can go from there.

@alanjaouen
Copy link
Contributor Author

Hi @ImJohnMDaniel ,

Thanks for your quick reply on this,

Have you seen the various videos about using the AT4DX framework as well as the VirtualDreamin2020 talk - "Architectural Considerations to Implementing DX and 2nd Generation Packaging"?

I based my implementation on the wiki, and these videos:

I will have a look at "Architectural Considerations to Implementing DX and 2nd Generation Packaging"

Would PackageA be placed in a "business layer" package or in a "common layer" package?

PackageA is in common layer.

Based on what I have heard you describe, it sounds like a good candidate for the AT4DX feature "Selector Method Injection", but let me know the answers to questions above and we can go from there.

I searched for this particular feature (before creating this issue), but didn't found anything online, is there any centralized documentation that reference this feature?

Thanks
Alan

@ImJohnMDaniel
Copy link
Collaborator

Ok. If PackageA is a common layer package then you are good.

There are two things that you are trying to do:

  • Add the new field that belongs to PackageB to the list of fields that the PackageA.AccountsSelector queries
  • Add a new method to the PackageA.AccountsSelector that queries by this new PackageB field.

Referenced examples are found in the AT4DX Sample Code repo.

Add a new field form PackageB to the PackageA.AccountsSelector -- "Selector Field Injection"

Selector Field Injection allows you to setup a field set in PackageB, and then include this new field that is only present in PackageB -- packageB_id__c. You then need to find the Custom Metadata Type object "Selector Config - Fieldset Inclusion" and add a CMDT record that binds the PackageB.fieldset to the PacakgeA default selector's SObject. That instructs the default selector for the SObject to include the additional fields specified in the fieldset.

In the AT4DX Sample Code repo, there is a new "Slogan" field added to the Account Sobject (e.g. equivalent to your PackageB packageB_id__c). That field was added to a fieldset called "SelectorInclusion_AccountFieldsMarketing". Now when the default Account selector for AT4DX Sample Code runs , the Slogan field is also included.

Add a new method to the PackageA.AccountsSelector that queries by this new PackageB field. -- "Selector Method Injection"

Selector Method Injection allows you to write a distinct class for this new method and, when the selector is called, this method class will be injected into the base selector class and operate as if it were simply a method that is directly part of the class itself.

In the AT4DX Sample Code, we had a need to query for Accounts where the Slogan field matched a specific string set. Obviously, since the Slogan field is not part of the base package (in your case, PackageA), we could not add the method directly to the AccountsSelector in PackageA. Instead, the "SelectBySloganSelectorMethod" class was created. This Selector Method class extends the AbstractSelectorMethodInjectable class and implements the ISelectorMethodInjectable interface. That contract requires the setup of the List<SObject> selectQuery() method where you can define the method that you need. This selectQuery() method behaves just like a normal selector method. That method has access to the base selector's newQueryFactory() method as well as all of the fields defined by the selector's field contract. You add fields to the base field contract and do pretty much anything that you need.

The only difference from a normal selector method is around the question of "how to pass parameters to the query class?" To do that, you define an inner class -- typically named "Parameters" -- that implements ISelectorMethodParameterable interface. You place whatever parameters that you will need for the query inside the Parameters class. Leading up to the selector method call, you would instantiate the Parameters class, add the input (for this AT4DX example, see the Parameters class sloganNameSet class variable) and then pass this along with the Selector Method class.

You can see an example of how this Selector Method is called in the AccountSloganRelatedTest class; starting at line 76. The Parameters class is setup like the following:

// Setup the injection parameter class
SelectBySloganSelectorMethod.Parameters queryParams = new SelectBySloganSelectorMethod.Parameters();
queryParams.sloganNameSet = new Set<String>{ slogan };

And the Selector Method is combined with the base AccountsSelector by using the selectInjection() method as seen on line 96

List<Account> accountsQueried = AccountsSelector.newInstance().selectInjection( SelectBySloganSelectorMethod.class, queryParams);

Hopefully this addresses your question. Let me know if something is still not clear or if I am not understanding your question correctly.

Hope this helps!

Cheers!

@alanjaouen
Copy link
Contributor Author

Thanks for your complete anwer, it will definitly help me 👍

@alanjaouen alanjaouen changed the title Selector Layer / question abour injecting method or criterias Selector Layer / question about injecting method or criterias Mar 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants