Install
$ agentstack add skill-emgreppi-business-central-ai-skill-implementing-al-interfaces ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Skill: AL Interfaces
Validation Gates
- After Step 2: Interface compiles, implementing codeunit compiles with all methods
- After Step 3: Enum converts to interface, method calls work polymorphically
- Final: Mock codeunit works in tests,
is/asoperators behave correctly (BC25+)
Note: BC16+ for basic interfaces. BC25+ for is/as operators and extensible interfaces.
Output: Interface declaration, implementing codeunits, extensible enum, and usage pattern.
Procedure
Step 1: Declare Interface
interface " I Provider"
{
procedure Execute(InputData: ): ;
procedure Cancel(TransactionId: Text; InputData: ): ;
procedure GetProviderName(): Text;
}
Placeholder Reference: | Placeholder | Description | Example | |-------------|-------------|---------| | ` | Type of service | Payment, Shipping, Notification | | , | Provider implementations | Stripe, DHL, Email | | | Main operation name | Payment, Shipment, Message | | | Input parameter type | Decimal, Record "Sales Header" | | | Return value type | Boolean, Text` |
Step 2: Create Implementing Codeunits
codeunit " " implements " I Provider"
{
procedure Execute(InputData: ):
begin
exit(CallAPI(InputData));
end;
procedure Cancel(TransactionId: Text; InputData: ):
begin
exit(CallCancelAPI(TransactionId, InputData));
end;
procedure GetProviderName(): Text
begin
exit('');
end;
local procedure CallAPI(InputData: ):
begin
// Provider-specific logic
end;
local procedure CallCancelAPI(TransactionId: Text; InputData: ):
begin
// Provider-specific logic
end;
}
Create additional codeunits for each provider (`, `, etc.) implementing the same interface.
Step 3: Create Enum with Implements
enum " Provider" implements " I Provider"
{
Extensible = true;
value(0; )
{
Implementation = " I Provider" = " ";
}
value(1; )
{
Implementation = " I Provider" = " ";
}
}
Step 4: Use Interface Polymorphically
codeunit " Manager"
{
procedure Process(var SourceRecord: Record ): Boolean
var
ProviderType: Enum " Provider";
IProvider: Interface " I Provider";
begin
ProviderType := SourceRecord." Provider";
IProvider := ProviderType; // Implicit conversion
if IProvider.Execute(SourceRecord.) then begin
SourceRecord." Processed" := true;
SourceRecord.Modify();
exit(true);
end;
exit(false);
end;
}
BC25+ Features: is/as Operators
// Check if interface supports specific type, then convert
if IProvider is " IAdvanced" then begin
IAdvanced := IProvider as " IAdvanced";
exit(IAdvanced.Partial(TransactionId, InputData, ''));
end;
exit(IProvider.Cancel(TransactionId, InputData));
Multiple interfaces: codeunit "..." implements "I", "IAdvanced", "IStatus"
Dependency Injection for Testing
Pattern: Store interface as codeunit variable, inject via Initialize(Provider) procedure.
codeunit " Processor"
{
var
ServiceProvider: Interface " I Provider";
procedure Initialize(Provider: Interface " I Provider")
begin
ServiceProvider := Provider;
end;
procedure Process(var SourceRecord: Record ): Boolean
begin
exit(ServiceProvider.Execute(SourceRecord.));
end;
}
Mock for tests: Create codeunit implementing interface with configurable behavior (SetShouldSucceed, GetCallCount).
See references/interface-patterns.md for complete mock implementation example.
Common Patterns
| Pattern | Description | |---------|-------------| | Provider/Strategy | Multiple implementations for same operation (payment, shipping) | | Factory | exit(ProviderType) - enum implicitly converts to interface | | Decorator | Wrap interface to add logging, validation, caching |
Important Notes
Best practices: Small focused interfaces, Extensible = true for partner extensions, use enums for selection.
Limitations: Only procedures (no properties/events/variables), only codeunits implement, cannot serialize to records.
Troubleshooting
| Issue | Fix | |-------|-----| | "does not implement interface" | Verify all interface methods exist with exact signatures | | Enum doesn't convert to interface | Check implements clause on enum declaration | | is/as operators not available | Requires BC25+ (2024 Wave 2) |
Feedback loop: Fix signature → Re-compile → Verify method calls work polymorphically.
References
See references/ folder for:
interface-patterns.md- Additional code examples
External Documentation
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: emgreppi
- Source: emgreppi/Business-Central-AI-Skill
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.