Dependency Injection in Business Central AL: Practical Guide
Learn how to apply dependency-injection principles in Microsoft Dynamics 365 Business Central AL using interfaces, replaceable implementations and factory-style selection.
What is dependency injection?
Dependency injection (DI) is a design technique where a component receives the behavior it depends on instead of creating or hard-coding that dependency itself.
Why use DI in Business Central AL?
- Reduce direct dependencies.
- Make implementations replaceable.
- Support multiple providers or strategies.
- Improve testability.
- Keep integration-specific logic outside core business processes.
Interfaces are the foundation
AL interfaces provide a natural contract between a consumer and an implementation.
interface "Notification Provider"
{
procedure SendMessage(Message: Text): Boolean;
}
Implement the contract
codeunit 50140 "Email Notification Provider" implements "Notification Provider"
{
procedure SendMessage(Message: Text): Boolean
begin
// Email implementation
exit(true);
end;
}
Inject the dependency
A procedure can receive the interface as a parameter. The consumer does not need to know which concrete provider is being used.
procedure NotifyCustomer(
Provider: Interface "Notification Provider";
Message: Text): Boolean
begin
exit(Provider.SendMessage(Message));
end;
Enum + interface pattern
An enum can represent the business choice while the interface represents the behavior.
enum 50140 "Notification Method"
{
Extensible = true;
value(0; Email) { }
value(1; SMS) { }
}A factory-style codeunit can map the selected enum value to the appropriate implementation. This keeps provider-selection logic in one place.
Dependency injection for integrations
DI is useful when Business Central connects to multiple CRM, e-commerce, shipping or middleware providers. Define a common contract and keep each provider's HTTP, authentication, JSON and mapping logic inside its implementation.
interface "Customer Sync Provider"
{
procedure SyncCustomer(CustomerNo: Code[20]): Boolean;
}
Example architecture
Business Process
|
v
Interface Contract
|
+---+---+
| | |
Provider A Provider B Test ProviderThe business process depends on the contract. Implementations can change independently as long as they satisfy that contract.
DI and automated testing
A production implementation may call an external service, while a test implementation can return predictable results without making a real HTTP request.
codeunit 50142 "Test Notification Provider"
implements "Notification Provider"
{
procedure SendMessage(Message: Text): Boolean
begin
exit(true);
end;
}
DI vs direct codeunit dependency
| Direct dependency | Interface-based dependency |
|---|---|
| Consumer knows the implementation | Consumer knows the contract |
| Replacement can require code changes | Implementations can be replaced more easily |
| Testing may depend on concrete services | A test implementation can be supplied |
Common mistakes
- Creating interfaces for logic that does not need abstraction.
- Building an unnecessarily complex factory.
- Mixing provider-specific HTTP logic into the main business process.
- Using vague or oversized interfaces.
- Assuming every AL solution needs a DI framework.
Best practices
- Keep interfaces small and focused.
- Inject behavior at clear boundaries.
- Keep external API and authentication details inside provider implementations.
- Use enums or configuration to select strategies when appropriate.
- Use test implementations for business-process testing.
- Introduce abstraction when it provides real replaceability, testability or reduced coupling.
Real-world use cases
- Multiple payment providers
- Multiple shipping providers
- Different e-commerce connectors
- Email/SMS notification providers
- Tax or pricing providers
- External API and middleware integrations
Frequently asked questions
Does AL support dependency injection?
AL supports the principles through interfaces, parameters and replaceable implementations. A separate general-purpose DI container is not required for these patterns.
Is DI useful for Business Central integrations?
Yes. It can separate provider-specific details from core business logic and make implementations easier to replace or test.
Should every codeunit use an interface?
No. Use abstraction where multiple implementations, replaceability, testability or reduced coupling provides a clear benefit.
Summary
Dependency injection is about controlling dependencies and keeping business logic flexible. In Business Central AL, interfaces provide a practical foundation: define a contract, implement it in one or more codeunits, and pass the required implementation into the business process.