lukethacoder / fflib.dev

⚡ Unofficial and semi-opinionated fflib documentation - Apex Enterprise Patterns
https://fflib.dev
MIT License
6 stars 0 forks source link

Feedback for “Domain Layer: Basic Example”, need Custom Metadata examples #5

Closed ShaolinDave closed 7 months ago

ShaolinDave commented 7 months ago

The documentation says to create a ApplicationFactory_DomainBinding Custom Metadata Record, but I'm not sure it's actually used.

I receive errors apparently because I don't have a Binding Custom Metadata Record, but I don't see any instructions on how to create it.

error with no Binding cmr: di_Injector.InjectorException: Binding for "iapplicationsobjectselector" and SObjectType "Contact" not found

error when attempting to create Binding cmr: IContacts cannot be constructed

ShaolinDave commented 7 months ago

Update #1: a new error while working with binding cmr: System.TypeException: Contacts does not have a no-arg constructor

The values I have on my Bindings cmr: Label: Contacts Binding Name: iapplicationobjectdomain Type: Apex To: Contacts Binding Oject: Contact

ShaolinDave commented 7 months ago

Update #2: Been tracing the code trying to find the issue. I'm writing all this for the Contact object instead of PortalUsers, but otherwise everything is taken from the Basic Example section.

The error occurs with this code in di_Binding.cls:

                Type toType = NameSpacePrefix == null ? Type.forName(className) : Type.forName(NamespacePrefix, className);
                if (toType == null)
                {
                    throw new BindingException('Apex binding ' + DeveloperName + ' implementation ' + To + ' does not exist');
                }

                Object toObject = toType.newInstance();

So on "Object toObject = toType.newInstance();" for the Basic Example toType would be "PortalUsers", and in my case is "Contacts"

Referring to the example code:

  // 1. Boilerplate code
  public static IPortalUsers newInstance(List<PortalUser__c> records) {
    return (IPortalUsers) Application.Domain.newInstance(records);
  }

  public static IPortalUsers newInstance(Set<Id> recordIds) {
    return (IPortalUsers) Application.Domain.newInstance(recordIds);
  }

  public PortalUsers(List<PortalUser__c> records) {
    super(records);
  }

  public class Constructor implements fflib_SObjectDomain.IConstructable {
    public fflib_SObjectDomain construct(List<SObject> sObjectList) {
      return new PortalUsers(sObjectList);
    }
  }

And yes, there is no PortalUsers.newInstance() without arguments, and in my case there is no Contacts.newInstance() without arguments. The newInstance() methods here that do have arguments are also what are actually being testing leading to this failure.

ShaolinDave commented 7 months ago

I got this working, though I'm not entirely sure how. I started over on the Selector Layer creation, including the Custom Metadata there, and I'm no longer receiving the error. I must have had some sort of typo the first time around. So Domain Layer is dependent on Selector Layer.