alguidelines/content/BCPatterns/event-bridge-pattern/index.md
2022-02-10 16:06:55 +01:00

3.2 KiB

+++ title = "Event Bridge Pattern" weight = 1180 +++ This is a guideline, some parts are optional (if there's no content, remove the whole paragraph).

<Created by (company), Described by (company)>

Abstract

In the world of interfaces, it is important to preserve (certain) events over multiple implementation of the interface.

Context

An app can have interfaces. It makes it possible for other apps to extend/change the implementations of a certain part of the business logic.

Like in this example, we have an interface, to implement different ways for getting weights from scales:

interface "IScale"
{
    procedure GetWeight(): Decimal;
    procedure Tare();
}

Problem

Multiple apps can subscribe to certain events of the app. When a new implementation is created, we need to make sure that these events are raised at the right times. If those events were published on the implementation codeunit, it might very well be that those events will not be raised, hard to find, or whatever.

So, if we would implement it like this, it isn't really extensible, as a different implemention would impement different events .. and it's not possible to subscribe to all of them (inculding future implementations)

codeunit 50407 "Scale Wrong" implements IScale
{

    procedure GetWeight() Result: Decimal;
    begin
        //TODO: Implement Bar GetWeight
        OnAfterGetWeight(Result);
    end;

    procedure Tare();
    begin
        //TODO: Implement Bar Tare
        OnAfterTare();
    end;

    [IntegrationEvent(false, false)]
    procedure OnAfterGetWeight(var Result: Decimal)
    begin
    end;

    [IntegrationEvent(false, false)]
    procedure OnAfterTare()
    begin
    end;
}

Description

To mitigate this problem, we can work with a new, dedicated, isolated, codeunit, with publish events to be able to raise them from different places.

codeunit 50406 "IScale Triggers"
{
    [IntegrationEvent(false, false)]
    procedure OnAfterGetWeight(var Result: Decimal)
    begin
    end;

    [IntegrationEvent(false, false)]
    procedure OnAfterTare()
    begin
    end;
}

This way, it's possible to raise the events in all the implementations:

codeunit 50405 "Scale Bar" implements IScale
{
    var
        IScaleTriggers: Codeunit "IScale Triggers";

    procedure GetWeight() Result: Decimal;
    begin
        //TODO: Implement Bar GetWeight
        IScaleTriggers.OnAfterGetWeight(Result);
    end;

    procedure Tare();
    begin
        //TODO: Implement Bar Tare
        IScaleTriggers.OnAfterTare();
    end;
}

Benefits

This new codeunit, with public events, makes the events accessible from all places, including new apps that are dependent from this app, and wants to extend the

The naming convention (both starting with "IScale") also makes it very easy to find that corresponding events for the interface.

When not to use

Obiously, the events should be carefully considered: only the events that make sense to "share" over all implementations, need this approach.

Discussions

Create a discussions-page of your pattern, and add the sentence "You can discuss this pattern here" with the right link to that discussions-page.