Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

title: ""
labels: ""
assignees: ""
---

**Describe the bug**
Expand All @@ -15,6 +14,7 @@ assignees: ''
(Please provide a public github repo with a full SFDX project that demonstrates the problem. If the repro case can be followed with a single example Apex class against a scratch org with just the fflib-apex-common and fflib-apex-mocks project deployed into it, you don't need to provide a github repo)

Steps to reproduce the behavior:

1. Create a scratch org as follows....
2. Run the following Anonymous Apex....
3. See error
Expand Down
7 changes: 3 additions & 4 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

title: ""
labels: ""
assignees: ""
---

**Is your feature request related to a problem? Please describe.**
Expand Down
5 changes: 2 additions & 3 deletions .github/workflows/deploy.and.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ on:
push:
pull_request_target:
workflow_dispatch:

jobs:
build:

runs-on: ubuntu-latest

steps:
Expand All @@ -26,7 +25,7 @@ jobs:
- name: Create the scratch org
run: sf org create scratch --definition-file config/project-scratch-def.json --set-default --duration-days 1 --no-track-source --alias fflibapexcommon
# - name: Install required dependency frameworks
# run: sf shane github src install --convert --githubuser apex-enterprise-patterns --repo fflib-apex-mocks --path sfdx-source/apex-mocks
# run: sf shane github src install --convert --githubuser apex-enterprise-patterns --repo fflib-apex-mocks --path sfdx-source/apex-mocks
- name: Clone fflib-apex-mocks repo
run: mkdir temp && git clone https://github.com/apex-enterprise-patterns/fflib-apex-mocks.git "temp/fflib-apex-mocks"
- name: Deploy and compile the fflib-apex-mocks codebase
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/manage.sf.api.versions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on:
workflow_dispatch:
inputs:
api-version:
description: 'api version in the format XX e.g 58'
description: "api version in the format XX e.g 58"
required: true
type: string
jobs:
Expand All @@ -16,7 +16,7 @@ jobs:
api-version: ${{inputs.api-version}}
- uses: peter-evans/create-pull-request@v5
with:
title: 'Bump API Versions to ${{inputs.api-version}}.0'
body: 'Automatically bumped by GitHub Actions '
branch: 'devops/bump-api-versions-v${{inputs.api-version}}.0'
commit-message: 'chore: bump api to v${{inputs.api-version}}.0'
title: "Bump API Versions to ${{inputs.api-version}}.0"
body: "Automatically bumped by GitHub Actions "
branch: "devops/bump-api-versions-v${{inputs.api-version}}.0"
commit-message: "chore: bump api to v${{inputs.api-version}}.0"
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ sfdx-source/untracked/
.execanon

# NPM Related
package.json
/node_modules
package-lock.json


sfdx-source/group*
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock.json
48 changes: 48 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"plugins": ["@prettier/plugin-xml", "prettier-plugin-apex"],
"overrides": [
{
"files": "*.xml",
"options": {
"xmlSelfClosingSpace": false,
"bracketSameLine": true,
"printWidth": 99999,
"tabWidth": 4,
"xmlWhitespaceSensitivity": "ignore",
"singleAttributePerLine": false
}
},
{
"files": "*{labels,validationRule,globalValueSet,field,md,flexipage}-meta.xml",
"options": {
"xmlSelfClosingSpace": false,
"bracketSameLine": true,
"printWidth": 99999,
"tabWidth": 4,
"xmlWhitespaceSensitivity": "preserve",
"singleAttributePerLine": false
}
},
{
"files": "*.{cmp,page,component,design,evt,auradoc}",
"options": {
"parser": "html"
}
},
{
"files": "*.js",
"options": {
"arrowParens": "always",
"bracketSpacing": true
}
},
{
"files": "**/aura/**/*.js",
"options": {
"arrowParens": "always",
"bracketSpacing": true,
"quoteProps": "preserve"
}
}
]
}
25 changes: 10 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,34 @@
FFLib Apex Common
=================
# FFLib Apex Common

![Push Source and Run Apex Tests](https://github.com/apex-enterprise-patterns/fflib-apex-common/workflows/Create%20a%20Scratch%20Org,%20Push%20Source%20and%20Run%20Apex%20Tests/badge.svg)


**Dependencies:** Must deploy [ApexMocks](https://github.com/apex-enterprise-patterns/fflib-apex-mocks) before deploying this library

<a href="https://githubsfdeploy.herokuapp.com?owner=apex-enterprise-patterns&repo=fflib-apex-common">
<img alt="Deploy to Salesforce"
src="https://raw.githubusercontent.com/afawcett/githubsfdeploy/master/src/main/webapp/resources/img/deploy.png">
</a>

Updates
=======
# Updates

- **December 2022**, **IMPORTANT CHANGE** - Support for native Apex User Mode was added to the library (see [discussion](https://github.com/apex-enterprise-patterns/fflib-apex-common/discussions/419)). For new projects, the old `enforceCRUD` and `enforceFLS` flags on `fflib_SObjectSelector` should be considered deprecated and the constructors that take `dataAccess` arguments should be used instead. Additionally, the introduction of `fflib_SObjectUnitOfWork.UserModeDML` provides an `IDML` implementation that supports `USER_MODE` or `SYSTEM_MODE`. `fflib_SObjectUnitOfWork.SimpleDML` (the default `IDML` implementation) should be considered deprecated. There are measurable performance benefits to using `SYSTEM_MODE` and `USER_MODE` (Apex CPU usage reduction). Additionally, the use of explicit `USER_MODE` and `SYSTEM_MODE` overrides the `with sharing` and `without sharing` class declaration and makes the expected behavior of DML and SOQL easier to understand.
- **April 2021**, **IMPORTANT CHANGE**, the fflib_SObjectDomain has been split into a domain (fflib_IDomain) and triggerhandler (fflib_ISObjectDomain). This change can impact existing projects, please review [this page](docs/202105-new-domain-structure.md) for more details.
- **April 2020**, **IMPORTANT CHANGE**, the directory format of this project repo was converted to [Salesforce DX Source Format](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_source_file_format.htm). While the GIT commit history was maintained, it is not visible on GitHub. If you need to see the history, either clone the repo and execute `git log --follow` from the command line or refer to this [tag](https://github.com/apex-enterprise-patterns/fflib-apex-common/tree/metadata-format-prior-to-dx-source-format-conversion) of the codebase prior to conversion.
- **April 2020**, **IMPORTANT CHANGE**, the directory format of this project repo was converted to [Salesforce DX Source Format](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_source_file_format.htm). While the GIT commit history was maintained, it is not visible on GitHub. If you need to see the history, either clone the repo and execute `git log --follow` from the command line or refer to this [tag](https://github.com/apex-enterprise-patterns/fflib-apex-common/tree/metadata-format-prior-to-dx-source-format-conversion) of the codebase prior to conversion.
- **September 2014**, **IMPORTANT CHANGE**, changes applied to support Dreamforce 2014 advanced presentation, library now provides Application factories for major layers and support for ApexMocks. More details to follow! As a result [ApexMocks](https://github.com/apex-enterprise-patterns/fflib-apex-mocks) must be deployed to the org before deploying this library. The sample application [here](https://github.com/apex-enterprise-patterns/fflib-apex-common-samplecode) has also been updated to demonstrate the new features!
- **July 2014**, **IMPORTANT CHANGE**, prior **23rd July 2014**, both the ``fflib_SObjectDomain.onValidate()`` and ``fflib_SObjectDomain.onValidate(Map<Id, SObject> existingRecords)`` methods where called during an on **after update** trigger event. From this point on the ``onValidate()`` method will only be called during on **after insert**. If you still require the orignal behaviour add the line ``Configuration.enableOldOnUpdateValidateBehaviour();`` into your constructor.
- **July 2014**, **IMPORTANT CHANGE**, prior **23rd July 2014**, both the `fflib_SObjectDomain.onValidate()` and `fflib_SObjectDomain.onValidate(Map<Id, SObject> existingRecords)` methods where called during an on **after update** trigger event. From this point on the `onValidate()` method will only be called during on **after insert**. If you still require the orignal behaviour add the line `Configuration.enableOldOnUpdateValidateBehaviour();` into your constructor.
- **June 2014**, New classes providing utilities to support security and dynamic queries, in addition to improvements to existing Apex Enterprise Pattern base classes. Read more [here](http://andyinthecloud.com/2014/06/28/financialforce-apex-common-updates/).

This Library
============
# This Library

Is derived from the **Dreamforce 2012** presentation on [Apex Enterprise Patterns](https://github.com/financialforcedev/df12-apex-enterprise-patterns) and progresses the patterns further with a more general ongoing home for them. It also adds some form of namespace qualification from the previous version. So that classes are grouped together more easily in the IDE's and packages. Below you can find comprehensive articles and videos on the use of these patterns. There is also a **working sample application** illustrating the patterns [here](https://github.com/apex-enterprise-patterns/fflib-apex-common-samplecode).

![Alt text](/images/patternsturning.png "Optional title")

Application Enterprise Patterns on Force.com
============================================
# Application Enterprise Patterns on Force.com

Design patterns are an invaluable tool for developers and architects looking to build enterprise solutions. Here are presented some tried and tested enterprise application engineering patterns that have been used in other platforms and languages. We will discuss and illustrate how patterns such as Data Mapper, Service Layer, Unit of Work and of course Model View Controller can be applied to Force.com. Applying these patterns can help manage governed resources (such as DML) better, encourage better separation-of-concerns in your logic and enforce Force.com coding best practices.

Documentation
-------------
## Documentation

- [Apex Sharing and applying to Apex Enterprise Patterns](http://andyinthecloud.com/2016/01/10/apex-sharing-and-applying-to-apex-enterprise-patterns/)
- [Tips for Migrating to Apex Enterprise Patterns](http://andyinthecloud.com/2015/09/30/tips-for-migrating-to-apex-enterprise-patterns/)
Expand All @@ -45,19 +39,20 @@ Documentation
- [Apex Enterprise Patterns - Service Layer](http://wiki.developerforce.com/page/Apex_Enterprise_Patterns_-_Service_Layer)
- [Apex Enterprise Patterns - Domain Layer](http://wiki.developerforce.com/page/Apex_Enterprise_Patterns_-_Domain_Layer)
- [Apex Enterprise Patterns - Selector Layer](https://github.com/financialforcedev/df12-apex-enterprise-patterns#data-mapper-selector)
- View slides for the **Dreamforce 2013** session [here](https://docs.google.com/file/d/0B6brfGow3cD8RVVYc1dCX2s0S1E/edit)
- View slides for the **Dreamforce 2013** session [here](https://docs.google.com/file/d/0B6brfGow3cD8RVVYc1dCX2s0S1E/edit)
- View slides for the **Dreamforce 2015** session [here](http://www.slideshare.net/andyinthecloud/building-strong-foundations-apex-enterprise-patterns)

**Related Webinars**

- [Advanced Apex Enterprise Patterns](https://www.youtube.com/watch?v=BLXp0ZP0cF0)
- [Apex Hours (August 2020): Apex Enterprise Patterns](https://www.apexhours.com/apex-enterprise-patterns/)

**Related Book**

- [Salesforce Platform Enterprise Architecture, 4th Edition, by Andrew Fawcett](https://www.amazon.com/Salesforce-Platform-Enterprise-Architecture-applications-ebook/dp/B0BD8TBT75/)

**Other Related Blogs**

- [Preview of Advanced Apex Patterns Session (Application Factory and ApexMocks Features)](http://andyinthecloud.com/2014/08/26/preview-of-advanced-apex-enterprise-patterns-session/)
- [Unit Testing with the Domain Layer](http://andyinthecloud.com/2014/03/23/unit-testing-with-the-domain-layer/)
- [FinancialForce Apex Common Updates](http://andyinthecloud.com/2014/06/28/financialforce-apex-common-updates/)

22 changes: 10 additions & 12 deletions config/multicurrency-scratch-def.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
{
"orgName": "apex-common",
"edition": "Developer",
"features": [
"MultiCurrency"
],
"settings": {
"currencySettings":{
"enableMultiCurrency": true
},
"lightningExperienceSettings": {
"enableS1DesktopEnabled": true
}
"orgName": "apex-common",
"edition": "Developer",
"features": ["MultiCurrency"],
"settings": {
"currencySettings": {
"enableMultiCurrency": true
},
"lightningExperienceSettings": {
"enableS1DesktopEnabled": true
}
}
}
12 changes: 6 additions & 6 deletions config/project-scratch-def.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"orgName": "apex-common",
"edition": "Developer",
"settings": {
"lightningExperienceSettings": {
"enableS1DesktopEnabled": true
}
"orgName": "apex-common",
"edition": "Developer",
"settings": {
"lightningExperienceSettings": {
"enableS1DesktopEnabled": true
}
}
}
57 changes: 32 additions & 25 deletions docs/202105-new-domain-structure.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,64 @@
# New domain structure
The new domain structure allows more flexibility of the object type a domain can contain.
This allows for the creation of compound-domains and domains of data-classes.

It also splits the functionality into a Domain Model [as described by Martin Fowler](https://www.martinfowler.com/eaaCatalog/domainModel.html) and a separate trigger handler.
This helps to structure the code better and makes it more clear which Apex code should be in the domain and which in the trigger handler.

The new domain structure allows more flexibility of the object type a domain can contain.
This allows for the creation of compound-domains and domains of data-classes.

It also splits the functionality into a Domain Model [as described by Martin Fowler](https://www.martinfowler.com/eaaCatalog/domainModel.html) and a separate trigger handler.
This helps to structure the code better and makes it more clear which Apex code should be in the domain and which in the trigger handler.

## Previous interface and implementation structure
| Interfaces | Implementation | Description |
|:---|:---|:---|
| fflib_ISObjectDomain | fflib_SObjectDomain | Used as Domain and trigger handler

| Interfaces | Implementation | Description |
| :------------------- | :------------------ | :--------------------------------- |
| fflib_ISObjectDomain | fflib_SObjectDomain | Used as Domain and trigger handler |

## New interface and implementation structure
| Interfaces | Implementation | Description |
|:---|:---|:---|
| fflib_IDomain | | Generic identifier for domains
| fflib_IObjects | fflib_Objects | Domains constructed with Objects, e.g. data-classes
| fflib_ISObjects | fflib_SObjects | Domain containing SObjectTypes, e.g. Accounts, Contacts
| fflib_ISObjectDomain | fflib_SObjectDomain | Used for trigger handlers and for legacy domains

See [this PR](https://github.com/apex-enterprise-patterns/fflib-apex-common/pull/300) for a detailed overview

| Interfaces | Implementation | Description |
| :------------------- | :------------------ | :------------------------------------------------------ |
| fflib_IDomain | | Generic identifier for domains |
| fflib_IObjects | fflib_Objects | Domains constructed with Objects, e.g. data-classes |
| fflib_ISObjects | fflib_SObjects | Domain containing SObjectTypes, e.g. Accounts, Contacts |
| fflib_ISObjectDomain | fflib_SObjectDomain | Used for trigger handlers and for legacy domains |

See [this PR](https://github.com/apex-enterprise-patterns/fflib-apex-common/pull/300) for a detailed overview
of all the code changes which were part of this change.

The [fflib-apex-common-samplecode](https://github.com/apex-enterprise-patterns/fflib-apex-common-samplecode)
also includes examples on how to structure the change into the
also includes examples on how to structure the change into the
[new domain](https://github.com/apex-enterprise-patterns/fflib-apex-common-samplecode/blob/master/sfdx-source/apex-common-samplecode/main/classes/domains/Accounts.cls)
and [trigger handler](https://github.com/apex-enterprise-patterns/fflib-apex-common-samplecode/blob/master/sfdx-source/apex-common-samplecode/main/classes/triggerHandlers/OpportunitiesTriggerHandler.cls)

## Known issues and how to resolve them


### _Issue:_ Ambiguous method signature: void setMock(MyDomainClass)
This happens when you try to mock an old domain class which is extended from fflib_SObjectDomain.

This happens when you try to mock an old domain class which is extended from fflib_SObjectDomain.

```apex
Application.Domain.setMock(mockAssetsDomain); // <<== generates Ambiguous method signature: void setMock
```

The issue can be resolved by casting the mock implementation to fflib_ISObjectDomain:
> Application.Domain.setMock( **(fflib_ISObjectDomain)** mockAssetsDomain);

[See this issue report for more information](https://github.com/apex-enterprise-patterns/fflib-apex-common/issues/347)
> Application.Domain.setMock( **(fflib_ISObjectDomain)** mockAssetsDomain);

[See this issue report for more information](https://github.com/apex-enterprise-patterns/fflib-apex-common/issues/347)

### _Issue:_ Illegal assignment from fflib_Domain to fflib_ISObjectDomain

The `newInstance` method signature of the Application Domain Factory (fflib_Application.DomainFactory) has changed into:
>public **fflib_IDomain** newInstance(***);

> public **fflib_IDomain** newInstance(\*\*\*);

If you have:

```apex
fflib_ISObjectDomain domain = Application.Domain.newInstance(sObjIds);
fflib_ISObjectDomain domain = Application.Domain.newInstance(sObjIds);
```

You need to change that into:
> fflib_ISObjectDomain domain = **(fflib_ISObjectDomain)** Application.Domain.newInstance(sObjIds);

[See this issue report for more information](https://github.com/apex-enterprise-patterns/fflib-apex-common/issues/346)
> fflib_ISObjectDomain domain = **(fflib_ISObjectDomain)** Application.Domain.newInstance(sObjIds);

[See this issue report for more information](https://github.com/apex-enterprise-patterns/fflib-apex-common/issues/346)
Loading