Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
APPLIES TO: Business Central 2026 release wave 2 and later.
When you publish an interface in an AL extension, dependent extensions can implement it. Changes to the interface's methods can break those extensions. This article describes the recommended lifecycle for safely adding, transitioning, and removing interface methods.
Method states
An interface method can be in the following states:
| State | Has body | Description |
|---|---|---|
| Required | No | All codeunits must implement this method. Contributes to the interface runtime identifier. |
| Default (optional) | Yes | Has a default implementation. Implementors can override it but don't have to. Doesn't affect the runtime identifier. |
| RequiredPending | Yes | Marked with [RequiredPending]. Still optional, but the compiler warns implementors to add their own implementation. |
| Obsolete Pending | Either | Marked for future removal. |
| Obsolete Removed | Either | Removed from the public API. |
Runtime identifier
The interface runtime identifier is a hash computed from the required (non-default) methods. It determines binary compatibility between the interface and its implementors at deployment.
Key rules:
- Default methods and RequiredPending methods don't contribute to the hash.
- Adding or removing default methods doesn't change the runtime identifier.
- Making a method required or removing a required method changes the runtime identifier.
- When the runtime identifier changes, dependent extensions must be recompiled.
Adding new methods to a published interface
You can't add a required method to a published interface directly. The AppSourceCop rule AS0066 prevents this change because it breaks all existing implementors.
Instead, add new methods as default methods (with a body). Default methods are safe to add because:
- Existing implementors continue to compile.
- The runtime identifier doesn't change.
- Dependent extensions don't need recompilation.
interface IPaymentProvider
{
// Existing required method
procedure ProcessPayment(Amount: Decimal): Boolean;
// New default method - safe to add
procedure ValidatePayment(Amount: Decimal): Boolean
begin
exit(true); // Default: always valid
end;
}
Transitioning from default to required
When a default method must eventually be implemented by all consumers, follow this two-phase process:
Phase 1 - Mark as RequiredPending
Add the RequiredPending attribute to the default method. The method keeps its body, so it stays optional.
[RequiredPending('Implement ValidatePayment for proper validation. This will become required in version 3.0.', '2.0')]
procedure ValidatePayment(Amount: Decimal): Boolean
begin
exit(true);
end;
The compiler emits warning AL0924 for any implementing codeunit that doesn't override the method:
Interface method 'IPaymentProvider.ValidatePayment' will become required. Reason: Implement ValidatePayment for proper validation. This change will become required in version 3.0. Tag: 2.0. Add an implementation now to avoid a future breaking change.
A code fix is available to help implementors: Implement RequiredPending interface method.
Phase 2 - Make required
In a later major version, remove the body and the [RequiredPending] attribute:
procedure ValidatePayment(Amount: Decimal): Boolean;
The method is now required. Any codeunit that doesn't add its own implementation fails to compile. The AppSourceCop emits AS0149 to warn about the runtime identifier change.
Important
Skipping Phase 1 and going directly from default to required triggers AS0148, which is an error.
Removing methods from an interface
To remove a method from a published interface, follow the standard Obsolete lifecycle:
- Obsolete Pending: Mark the method with
[Obsolete('Pending', 'Use method Y instead.')]. Callers receive a warning. - Obsolete Removed: In a later version, change to
[Obsolete('Removed', 'Use method Y instead.')]. Callers receive an error. - Delete: In a subsequent version, remove the method entirely.
Note
Removing a required method changes the runtime identifier (AS0149). Removing a default method doesn't change the runtime identifier but still triggers AS0018.
Summary of AppSourceCop rules
The following AppSourceCop rules enforce the interface method lifecycle:
| Rule | What it validates | Severity |
|---|---|---|
| AS0066 | New required method on published interface | Error |
| AS0148 | Default method made required without [RequiredPending] first |
Error |
| AS0149 | Runtime identifier changed (required method added or removed) | Warning |
| AS0072 | Tag version must match configured target | Hidden |
| AS0073 | Tag must be set | Hidden |
| AS0074 | Tag must not change unless attribute is newly added | Hidden |
| AS0075 | Reason must be set | Warning |
| AS0076 | Tag must match configured pattern | Hidden |
Code fixes
The compiler provides code fixes to help implementers:
| Diagnostic | Code fix | Description |
|---|---|---|
| Missing required methods | Implement required interface methods | Adds stubs for required methods only |
| Missing required methods | Implement all interface methods | Adds stubs for required and default methods |
| RequiredPending warning (AL0924) | Implement RequiredPending interface method | Adds a stub for the RequiredPending method |
All code fixes support Fix All scopes (Document, Project, Solution) for batch application.
Lifecycle diagram
The following diagram shows the complete lifecycle of an interface method:
┌──────────────────┐
┌────────>│ Default method │──────────────┐
│ │ (optional, body) │ │
│ └────────┬─────────┘ │
│ │ │
Add new method Add [RequiredPending] Add [Obsolete('Pending')]
│ │ │
│ v v
│ ┌──────────────────┐ ┌──────────────────┐
│ │ RequiredPending │ │ Obsolete Pending │
│ │ (optional+warn) │ │ │
│ └────────┬─────────┘ └────────┬─────────┘
│ │ │
│ Remove body [Obsolete('Removed')]
│ │ │
│ v v
│ ┌──────────────────┐ ┌──────────────────┐
│ │ Required method │ │ Obsolete Removed │
│ │ (no body) │ │ │
│ └──────────────────┘ └────────┬─────────┘
│ │
│ Delete method
│ │
│ v
└────────────────────────────────── (method removed)
Related information
Interfaces in AL
RequiredPending attribute
Obsolete attribute
Extending interfaces in AL
Obsolete objects and tags