Unit of Work - cdelfattore/apex-enterprise-patterns GitHub Wiki

Introduction

Unit of work will maintain a list of objects that are being created, edited and deleted and coordinates the writing of the changes to the database.

Getting Started

To implement a new instance of unit of work:

fflib_ISObjectUnitOfWork uow = Application.UnitOfWork.newInstance();

Use only one unit of work instance throughout the scope of a service method. If multiple service methods are called, pass the unit of work instance as a parameter to other service methods.

public void parentMethod()
{
	fflib_ISObjectUnitOfWork uow = Application.UnitOfWork.newInstance();
	childMethodA(uow);
	childMethodB(uow);
	uow.commitWork();
}

public void childMethodA(fflib_ISObjectUnitOfWork uow)
{
	...
}

public void childMethodB(fflib_ISObjectUnitOfWork uow)
{
	...
}

This is a very basic example. The idea is to think about creating your service methods in a way to that they can be modularized and called by other methods, without doing the same action twice or having the two different methods doing similar things. We want to promote code reuse and eliminate code duplication.

Available Methods

These are the most common methods used in the unit of work interface.

fflib_ISobjectUnitOfWork.registerNew(...); //Create a new record
fflib_ISobjectUnitOfWork.registerDirty(...); //Update a record
fflib_ISobjectUnitOfWork.registerDeleted(...); //Delete a record
fflib_ISobjectUnitOfWork.commitWork();

A complete list of all the methods available to fflib_ISObjectUnit of work can be found here. This will also include descriptions.

Application class

An Application apex class is needed in order to use the fflib library. In the Application class, the objects that are available to utilize unit of work are added to the UnitOfWork variable (a fflib_Application.UnitOfWorkFactory instance).

The objects need to be added in dependency order. In the below example you can see that account object is listed before the opportunity object. The reasons for this is you can't create an opportunity without having the Id of the account related to it. With unit of work you can create the opportunity and the account in one commitWork() call. The account will be created first and the AccountId on the opportunity will automatically be created.

// Configure and create the UnitOfWorkFactory for this Application
public static final fflib_Application.UnitOfWorkFactory UnitOfWork = 
	new fflib_Application.UnitOfWorkFactory(
			new List<SObjectType> {
				Account.SObjectType,
				Invoice__c.SObjectType,
				InvoiceLine__c.SObjectType,
				Opportunity.SObjectType,
				Product2.SObjectType,
				PricebookEntry.SObjectType,
				OpportunityLineItem.SObjectType
			});

Full example of an Application class can be found here.

Full example

View the Service page example in this wiki for a full code example.