From 537b7caf246ef52c0bb383705231f005d3defffe Mon Sep 17 00:00:00 2001 From: waldo1001 Date: Thu, 10 Feb 2022 16:06:55 +0100 Subject: [PATCH] Event Bridge Patten --- .../BCPatterns/event-bridge-pattern/index.md | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 content/BCPatterns/event-bridge-pattern/index.md diff --git a/content/BCPatterns/event-bridge-pattern/index.md b/content/BCPatterns/event-bridge-pattern/index.md new file mode 100644 index 00000000..3a9beac1 --- /dev/null +++ b/content/BCPatterns/event-bridge-pattern/index.md @@ -0,0 +1,116 @@ ++++ +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: + +```AL +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) + +```AL +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: + +```AL +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](https://github.com/microsoft/alguidelines/discussions/66)" with the right link to that discussions-page. \ No newline at end of file