Chapter 17: Advanced AL Features
Objectives
By the end of this chapter you will be able to:
- Implement publisher/subscriber event patterns with clear responsibility boundaries
- Design extensibility points without hard-coding dependencies
- Use interfaces and dependency inversion for testable, modular AL code
- Evaluate advanced patterns against maintainability and upgrade safety
17.1 Eventing with publishers and subscribers
Events let you extend behavior without editing base logic directly.
codeunit 50130 "Loan Events"
{
[IntegrationEvent(false, false)]
procedure OnInstallmentMarkedPaid(LoanNo: Code[20]; InstallmentNo: Integer)
begin
end;
}
codeunit 50131 "Loan Notifications"
{
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Loan Events", 'OnInstallmentMarkedPaid', '', false, false)]
local procedure HandleInstallmentMarkedPaid(LoanNo: Code[20]; InstallmentNo: Integer)
begin
// Send notification, write telemetry, or enqueue follow-up work
end;
}
This pattern builds on the extension concepts from Chapter 11 in a way that is safe for production.
17.2 Interfaces and dependency inversion
Use interfaces when more than one implementation is possible.
interface "IRiskScoringProvider"
{
procedure GetRiskScore(VendorNo: Code[20]): Decimal;
}
codeunit 50132 "Default Risk Scoring Provider" implements "IRiskScoringProvider"
{
procedure GetRiskScore(VendorNo: Code[20]): Decimal
begin
exit(0);
end;
}
The calling code stays the same while the implementations change.
17.3 Advanced pattern selection criteria
Use advanced features only when they solve a real problem:
- Event subscribers for extension and decoupling
- Interfaces for replaceable strategies
- Single-instance codeunits only when you truly need state shared within a session
Overusing them in simple scenarios adds maintenance cost.
17.4 Testing advanced behavior
Advanced patterns need tests too:
- Verify that subscribers run only on the events they are meant for.
- Validate interface implementations against consistent contracts.
- Make sure fallback behavior exists for when optional integrations are unavailable.
This is the same regression mindset as in Chapter 14.
Chapter summary
In this chapter you:
- Implemented event-driven extension points that keep code safely decoupled
- Applied interface-based design for replaceable behavior
- Weighed when advanced AL patterns are justified
- Tied advanced design back to testability and upgrade safety
Tasks
- Publish an event. Add an integration event to your loan-management flow.
- Subscribe responsibly. Create one subscriber codeunit that reacts without duplicating core logic.
- Introduce an interface. Define one interface and one implementation for a replaceable service.
- Try it yourself. Explain one case where a simple direct call is better than an event + subscriber chain.
Check your work: advanced patterns should extend Chapter 9 logic and Chapter 11 packaging without weakening clarity or testability.