Email this post as a PDFDevelopment · 6 October 2026 · 2 min read

Interfaces and enums in AL: a practical guide with a real example

Enums gave AL an extensible list type; interfaces gave it a way to vary behaviour by that list without a case statement. Together they are the pattern behind price calculation, document sending and most modern base-application design. A worked example from an enum value to a working implementation another app can extend.

Contents
  1. The problem
  2. 1. The interface
  3. 2. The enum, bound to it
  4. 3. The implementations
  5. 4. The caller
  6. 5. Someone else adds a carrier
  7. Rules of thumb

The patterns post named the strategy pattern; this is the full worked version, end to end, because it is the one most worth having in muscle memory.

The problem

A courier shipment has a carrier. Each carrier has its own API, label format and tracking URL. The naive code is a case Shipment.Carrier of in three procedures, and every new carrier edits all three.

1. The interface

interface "CON ICarrier"
{
    procedure Send(var Shipment: Record "CON Courier Shipment");
    procedure GetLabel(Shipment: Record "CON Courier Shipment"; var TempBlob: Codeunit "Temp Blob");
    procedure TrackingUrl(Shipment: Record "CON Courier Shipment"): Text;
}

2. The enum, bound to it

enum 50120 "CON Carrier" implements "CON ICarrier"
{
    Extensible = true;
    DefaultImplementation = "CON ICarrier" = "CON Carrier Not Set";
    value(0; " ") { Caption = ' '; }
    value(1; RoyalMail) { Caption = 'Royal Mail'; Implementation = "CON ICarrier" = "CON Carrier Royal Mail"; }
    value(2; DPD) { Caption = 'DPD'; Implementation = "CON ICarrier" = "CON Carrier DPD"; }
}

Each value names the codeunit that implements the interface for it. DefaultImplementation covers values that do not specify one (and values other apps add without an implementation).

3. The implementations

codeunit 50121 "CON Carrier Royal Mail" implements "CON ICarrier"
{
    procedure Send(var Shipment: Record "CON Courier Shipment")
    begin
        // Royal Mail-specific API call
    end;
    procedure GetLabel(Shipment: Record "CON Courier Shipment"; var TempBlob: Codeunit "Temp Blob")
    begin
    end;
    procedure TrackingUrl(Shipment: Record "CON Courier Shipment"): Text
    begin
        exit(StrSubstNo(RoyalMailTrackUrlTok, Shipment."Tracking No."));
    end;
}

The compiler enforces that every procedure in the interface is implemented. Nothing in the implementation knows about the others.

4. The caller

procedure Send(var Shipment: Record "CON Courier Shipment")
var
    Carrier: Interface "CON ICarrier";
begin
    Shipment.TestField(Carrier);
    Carrier := Shipment.Carrier;   // enum to interface: the platform picks the codeunit
    Carrier.Send(Shipment);
end;

That is the whole dispatch. No case statement, anywhere.

5. Someone else adds a carrier

enumextension 60100 "FAB Carrier Ext" extends "CON Carrier"
{
    value(60100; Evri) { Caption = 'Evri'; Implementation = "CON ICarrier" = "FAB Carrier Evri"; }
}

A different app, a different publisher, no change to your code. Your pages show the new value because the field is the enum; your dispatch calls the new codeunit because the value names it.

Rules of thumb

  • Interfaces are for behaviour that varies by a type. If there is one implementation and will only ever be one, it is just a codeunit.
  • Keep interfaces small (three to six procedures). Split by concern rather than making one giant "ICarrier does everything".
  • Interfaces cannot have fields or state; implementations get what they need as parameters.
  • Interface procedures are public by definition; keep the rest of the implementing codeunit local.
  • Changing an interface (adding a procedure) breaks every implementation, including other apps'. Add a new interface ("CON ICarrier v2") and have the enum implement both for a release.
  • Name interfaces with a leading I (naming post).

Once you have done this once, you will see it everywhere in the base application: "Price Calculation", "Document Sending Profile", the e-document framework, the AI agents. It is how Microsoft makes a behaviour extensible, and it is how you should.

Email this post as a PDF
A branded PDF of this post, sent to your inbox to keep, print or share. Copy in colleagues if you like.
We only use these addresses to send this PDF. Nobody is added to a mailing list. Mike at Business Boxed receives a copy. See our privacy notice.
Email this post
Talk to us
Want this done in your Business Central?
Book a 30 minute callGet the monthly newsletter

Related posts