1
We're currently migrating a legacy codebase to AL and one of our codeunits we need to convert present a challenge. Our app is designed to be modular (thus we have a core extension .app, as well as one or more mutually exclusive subsidiary extension apps that both depend on the core product).

The functionality of one of our objects varies depending on what extensions are loaded in the database. Events are not easily doable due to the object's use of several global variables and the statefulness of the object logic itself.

I understand that enum interfaces are in the roadmap pipeline. It would be great to see that concept expanded to include interfaces at the object level to solve this challenge (i.e. define interfaces for entire codeunits). The pattern would be similar to c# interface implementations.

pseudo code is as follows. Let's assume we have three .extension apps.

App 1 - core extension .app
App 2 - North America extension .app (depends on app 1)
App 3 - Europe extension .app (depends on app 1)

//resides in the core extension .app
//-------------------------------------
interface 50000 MyInterface
{

procedure Foo()
begin
//no code in here since it's simply an interface method definition. compiler can throw an error if code is
//found here or local variables are defined.
end;
}

//resides in the core extension app
//------------------------------------
codeunit 50000 MyInterfaceEventPublisher
{
public event publisher OnGetInterfaceInstance(instance: interface MyInterface; Context: code[20])
}

//resides in the a north-america subsidiary app
//-------------------------------------------------
codeunit 50001 MyNorthAmericaObject implements MyInterface
{
//compiler would throw an error if Foo isn't implemented.
procedure Foo()
begin
//implement north america specific functionality here
end;
}

//resides in an europe subsidiary .app
codeunit 50002 MyEuropeObject implements MyInterface
{
//compiler would throw an error if Foo isn't implemented.
procedure Foo()
begin
//implement europe specific functionality here
end;
}

//resides in north america subsidiary.app
codeunit 50003 MyNorthAmericaSubscriber
{
event subscriber OnGetInterfaceInstance(var instance: interface MyInterface; Context: code[20])
var
codeunitInstance: codeunit MyNorthAmericaObject ;
begin
//compiler would throw an error if MyNorthAmericaObject does not implement the intended interface
IF Context = 'NA' then
instance := codeunitInstance;
end;
}

//resides in europe subsidiary .app
codeunit 50004 MyEuropeSubscriber
{
event subscriber OnGetInterfaceInstance(var instance: interface MyInterface; Context: code[20])
var
codeunitInstance: codeunit MyEuropeObject ;
begin
//compiler would throw an error if MyEuropeObject does not implement the intended interface
IF Context = 'EU' then
instance := codeunitInstance;
end;
}

With this pattern, our core extension .app would not need *any* awareness of codeunit 50001 MyNorthAmericaObject nor codeunit codeunit 50002 MyEuropeObject. All it cares is to get a legit interface object instance based on whatever subsidiary extensions are installed.

I don't think object types other than enums and codeunits shoud be able to implement interfaces purely based on the potential complexity of abstracting a table or report via interfaces.

Category: Development
STATUS DETAILS
Completed
Ideas Administrator

Thank you for this suggestion! This is being released in 2020 Wave 1, and includes new interface object (defintion), ability to implement (one or more) interfaces (code units), passing variables by interface, compiler support checking implementations, code action for adding stubs for missing interface members, as well as interface in enums (being extensible) allowing enum values to decide on/return an actual code implementation fulfilling an interface, thereby allowing plugable business logic following strategy pattern

Best regards,
Business Central Team