How to Extend Codeunits in AL

Overview of Microsoft Dynamics 365 Business Central

Unlike tables, pages, or reports, codeunits cannot be extended using a “codeunit extension” object. This often confuses learners coming from other AL objects. Instead, Business Central provides controlled patterns to extend or influence codeunit behavior without modifying the original codeunit.

This page explains how codeunits are extended in practice, why direct extension is not allowed, and which supported mechanisms Microsoft provides to customize or enhance codeunit logic in an upgrade-safe way.

The goal is to help learners understand real extensibility patterns, not imaginary syntax.


Why Codeunits Cannot Be Directly Extended

Codeunits represent executable business logic. Allowing arbitrary extensions of executable logic would:

• Break execution flow
• Create unpredictable behavior
• Introduce upgrade and security risks

Because of this, AL does not support codeunitextension

Instead, codeunits are extended indirectly using well-defined mechanisms that preserve control and predictability.

The Three Supported Ways to Extend Codeunit Behavior

In Business Central, codeunit behavior is extended using three primary patterns:

1. Event Publishers and Subscribers
2. Interfaces and Implementations
3. Public Procedures and Wrapper Codeunits

Each pattern exists for a specific architectural reason.

1. Extending Codeunits Using Events (Primary Pattern)

The most common and recommended way to extend codeunit behavior is through events.

Standard codeunits publish events at key points in their logic. Custom extensions subscribe to these events and add behavior without modifying the original codeunit.

Conceptual Explanation

The base codeunit:

• Owns the process
• Decides when extension is allowed
• Raises events intentionally

The extension:

• Listens to events
• Adds logic safely
• Never takes control of execution

This is the foundation of upgrade-safe extensibility.

Example: Subscribing to a Codeunit Event

AL

codeunit 50170 "Customer Feedback Subscriber"
{
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Customer Feedback Management",
                     'OnAfterFeedbackCreated', '', false, false)]
    procedure AfterFeedbackCreated(CustomerNo: Code[20])
    begin
        Message('Feedback created for customer %1', CustomerNo);
    end;
}
    

This example:

• Extends behavior without modifying the codeunit
• Runs only when the event is raised
• Keeps logic isolated and safe

Note: Event publishing itself is covered in the next topic.

2. Extending Codeunits Using Interfaces (Strategy Pattern)

Interfaces allow you to replace or vary behavior in a controlled and explicit way. This is useful when:

• Multiple implementations are possible
• Behavior must change based on setup
• Logic must be swappable

Conceptual Explanation

An interface defines what must be done.

Codeunits define how it is done.

The calling codeunit works only with the interface, not the implementation.

Example: Interface definition

AL

interface "IFeedbackProcessor"
{
    procedure ProcessFeedback(CustomerNo: Code[20]);
}
    

Example: Implementation codeunit

AL

codeunit 50171 "Default Feedback Processor" implements "IFeedbackProcessor"
{
    procedure ProcessFeedback(CustomerNo: Code[20])
    begin
        Message('Default processing for %1', CustomerNo);
    end;
}
    

Example: Usage in a main codeunit

AL

procedure RunProcessor(Processor: Interface "IFeedbackProcessor")
begin
    Processor.ProcessFeedback("Customer No.");
end;
    

This pattern:

• Allows behavior replacement
• Avoids conditional logic
• Is explicit and testable

3. Extending Codeunits Using Public Procedures

Another supported pattern is wrapping existing codeunits by calling their public procedures from new codeunits.

Conceptual Explanation

The base codeunit:

• Exposes public procedures
• Remains unchanged

The extension codeunit:

• Calls base logic
• Adds pre- or post-processing
• Controls when base logic executes

Wrapper Codeunit Example

AL

codeunit 50172 "Extended Feedback Management"
{
    procedure CreateFeedbackWithLog(CustomerNo: Code[20]; FeedbackText: Text[250])
    var
        BaseMgt: Codeunit "Customer Feedback Management";
    begin
        BaseMgt.CreateFeedback(CustomerNo, FeedbackText);
        Message('Feedback logged with extension logic.');
    end;
}
    

This pattern is useful when:

• Events are not available
• Logic must be reused and extended
• You control how the wrapper is called

What You Cannot Do When Extending Codeunits

It is important to be explicit about limitations.

You cannot:

• Modify standard codeunit logic directly
• Override existing procedures
• Inject logic arbitrarily into execution flow
• Change transaction boundaries invisibly

These restrictions exist to protect system stability.

Choosing the Right Extension Pattern

Which pattern you use depends on intent:

Events → Add behavior safely
Interfaces → Replace or vary behavior
Wrappers → Reuse and extend logic

Understanding this choice is a core AL architecture skill.

Common Beginner Mistakes When Extending Codeunits

Developers often:

• Expect a codeunit extension object to exist
• Put all logic into subscribers
• Overuse wrappers instead of events
• Create circular dependencies

Avoiding these mistakes leads to clean, upgrade-safe solutions.

Summary

Codeunits cannot be extended directly, but Business Central provides powerful and safe mechanisms to extend their behavior. Events, interfaces, and wrapper patterns allow developers to add or alter logic without breaking upgrades or stability.

A well-designed extension:

• Respects ownership of logic
• Uses events first
• Applies interfaces deliberately
• Avoids invasive patterns

Understanding how to extend codeunits correctly is essential before learning Event Publishers and Subscribers.

Hot Topics in Business Central

Next Steps in Business Central