AL DEVELOPMENT • DESIGN PATTERNS

Interfaces in Business Central AL: Complete Beginner Guide

Learn how interfaces work in Microsoft Dynamics 365 Business Central AL and how they help you separate contracts from implementations, reduce dependencies and build flexible business logic.

Dynexal · Business Central AL Development

What is an interface?

An interface defines a contract: it describes which procedures an implementation must provide, without defining the implementation itself. A codeunit can implement an interface and provide the actual business logic.

Simple idea: The interface says what a component can do; the implementing codeunit decides how it does it.

Why use interfaces in Business Central?

Basic interface syntax

interface "Payment Provider"
{
    procedure ProcessPayment(Amount: Decimal): Boolean;
}

The interface declares a procedure. It does not contain the implementation of that procedure.

Implementing an interface in a codeunit

codeunit 50130 "Card Payment Provider" implements "Payment Provider"
{
    procedure ProcessPayment(Amount: Decimal): Boolean
    begin
        // Card payment logic
        exit(true);
    end;
}

The implementing codeunit must provide the procedures declared by the interface.

Multiple implementations

The real advantage becomes clear when several components implement the same contract.

codeunit 50131 "Cash Payment Provider" implements "Payment Provider"
{
    procedure ProcessPayment(Amount: Decimal): Boolean
    begin
        // Cash payment logic
        exit(true);
    end;
}

codeunit 50132 "Card Payment Provider" implements "Payment Provider"
{
    procedure ProcessPayment(Amount: Decimal): Boolean
    begin
        // Card payment logic
        exit(true);
    end;
}

Both codeunits expose the same operation through the interface while keeping their implementation details separate.

Using an interface variable

An interface variable can reference an implementing object. This lets business logic work with the contract instead of depending directly on one implementation.

var
    PaymentProvider: Interface "Payment Provider";
    PaymentResult: Boolean;
begin
    PaymentProvider := "Card Payment Provider";
    PaymentResult := PaymentProvider.ProcessPayment(1500);
end;

The important design benefit is that the calling code can depend on the interface rather than a concrete implementation.

Interface with an Enum

A common practical pattern is to use an enum to select an implementation. The enum represents the business choice while the interface represents the behavior.

enum 50130 "Payment Method"
{
    Extensible = true;

    value(0; Cash) { }
    value(1; Card) { }
}

A factory-style codeunit can then map the selected method to the appropriate implementation. This keeps selection logic separate from payment processing logic.

Polymorphism in AL

Polymorphism means that the same interface call can execute different implementations. For example, calling ProcessPayment through the interface can execute card, cash or another future payment provider implementation.

procedure ExecutePayment(PaymentProvider: Interface "Payment Provider"; Amount: Decimal): Boolean
begin
    exit(PaymentProvider.ProcessPayment(Amount));
end;

This procedure does not need to know which concrete provider is being used.

The is operator

The is operator can be used when you need to determine whether a value is compatible with a particular interface or type.

if PaymentProvider is "Payment Provider" then
    Message('A payment provider is available.');

Use type checks only when they are genuinely needed. In many designs, simply programming against the interface is cleaner.

The as operator

The as operator can be used for type casting when a compatible value needs to be treated as another type.

SomeInterface := SomeValue as "Payment Provider";
Important: Use casting carefully. Prefer a clear interface contract over frequent runtime type checks and casts.

Extending an interface

AL supports extending interfaces. An extended interface can add additional procedures while preserving the original contract for existing implementations where appropriate. Check the target Business Central version because interface language features can evolve between platform versions.

interface "Advanced Payment Provider" extends "Payment Provider"
{
    procedure RefundPayment(Amount: Decimal): Boolean;
}

Real-world example: shipping providers

Interfaces are useful when a Business Central solution may integrate with multiple shipping providers.

interface "Shipping Provider"
{
    procedure CreateShipment(DocumentNo: Code[20]): Text;
    procedure CancelShipment(ShipmentId: Text): Boolean;
}

Separate codeunits could implement the contract for DHL, FedEx, UPS or an internal logistics service. The sales or warehouse business logic can work with the interface instead of hard-coding one provider.

Interfaces and dependency reduction

Without an interface, a business process may directly depend on a specific codeunit. Replacing that implementation can then require changes in several places. With an interface, the process can depend on the contract and the implementation can change independently.

Business Process
       |
       v
Shipping Provider Interface
       |
   +---+---+
   |   |   |
 DHL UPS Custom

Interfaces and automated testing

Interfaces can make testing easier because business logic can be designed around a contract rather than a concrete external service. A test-oriented implementation can provide controlled behavior while the production implementation calls the real service.

Common mistakes

Best practices

Interface vs codeunit

InterfaceCodeunit
Defines a contractContains executable business logic
Can have multiple implementationsProvides a concrete implementation
Helps abstraction and polymorphismExecutes procedures and logic

Frequently asked questions

Can one codeunit implement an interface?

Yes. A codeunit can implement an interface by declaring the interface in its declaration and providing the required procedures.

Can multiple codeunits implement the same interface?

Yes. This is one of the main reasons to use interfaces: multiple implementations can follow the same contract.

Should every codeunit use an interface?

No. Interfaces are most useful when you need abstraction, multiple implementations, replaceable strategies or reduced coupling.

Are interfaces useful for Business Central integrations?

Yes. They can separate integration contracts from provider-specific HTTP, authentication or mapping logic.