Importance of interfaces

Completed

By nature of enum extensibility, the adoption of interfaces and enums allows you to write business logic that can be replaced later without impacting the consuming code, assuming that the new functionality complies with the defined interface. The following sections provide some examples of this scenario.

Example 1: Vehicle management

In this scenario, you need to add support for managing vehicles. You could define an interface that expresses the contract for capabilities of a vehicle, such as the max speed or payload capacity.

Screenshot of a diagram that shows an interface for a vehicle with car, truck, and bus variables.

Now, different vehicle types could be implemented, such as car, truck, and bus, all of which complies with the interface contract. With this scenario, consuming code can use the concept of polymorphism to create a variable of type interface and call methods on the interface, which will work regardless of whether a car, truck, or bus is passed in the variable.

Example 2: Price calculation

Another example is taken from the base application in 2020 Wave 1 (version 16), where interfaces are used in various places for adding extensible business logic. One such place is PriceCalculation for sales documents, where an interface defines the abilities of calculating prices. Two implementations are provided: one similar to 2019 Wave 2 (version 15) for backward compatibility and a new implementation for version 16.

Screenshot of a diagram showing an interface for Price Calculation with version 15 and version 16 variables.

When declaring the interface, you first need to consider the new interface object. Note that it doesn't have an object ID because it can't be run by itself. The interface also has a name.

The interface then defines its capabilities through procedures, but only with signatures: Name, parameters, return type, and visibility. The interface doesn't contain implementation of the procedures; instead, it must be implemented by other objects.

Screenshot of AL code for the Price Calculation interface with the ApplyDiscount procedure highlighted.

The following screenshot shows an example of implementing the Price Calculation interface. A codeunit can implement multiple interfaces, which are delimited by commas. The codeunit must implement all interface methods.

Screenshot of AL code with implements Price Calculation and ApplyDiscount procedure highlighted.

The compiler validates that a code unit complies with the interfaces that it implements. If methods are missing, a QuickFix CodeAction is available for you to add signature stubs for missing interface methods.

Tip

You can use this process when you are first creating the implementation to quickly get going.

Screenshot of AL code with implement interface the price calculation interface highlighted.

Now, different code units can implement the same interface differently. In this scenario, another code unit implements the Price Calculation interface, which in this case is Price Calculation for version 15.

Screenshot of AL code with price calculation version 15 and the ApplyDiscount procedure highlighted.

As shown in the image, the actual implementation of the methods, such as ApplyDiscount, are different.

Extensible enums support implementing an interface. The enum value can be assigned to an interface variable that can initialize the interface. In this way, you can use the enum to choose the specific implementation to use for a given interface. In this scenario, you would choose which PriceCalculation implementation to use: v15 or v16.

Screenshot of AL code with implements price calculation and the implementation highlighted.

As an example, if you want to replace PriceCalculation, then you would follow these steps:

  1. Create a new implementation for the PriceCalculation interface.

  2. Extend enum with a value returning new implementation.

  3. Configure to use a new implementation.

For more information, see Extending Price Calculations.