Event broker

From Axaptapedia

Jump to: navigation, search

Contents

[edit] Purpose

[edit] Download

SysEventBroker.xpo (11 KB)

[edit] Implementaion

Three classes are provided:

  1. SysEventListener is the interface class for a "listener"
    • gotEvent: every listener must implement
  2. SysEventInfo is an implementation for a listener, which simply put received information on the Infolog
    • main: contains a simple test case
  3. SysEventBroker, which client classes use to register and notify listeners, it implements the following methods:
    • addListener: to register a listener
    • removeListener: to unregister a listener
    • fireEvent: to fire an event and to notify listeners via the gotEvent method

[edit] Example

static void SysEventTest(Args _args)
{
    SysEventBroker broker = SysEventBroker::construct();
    SysEventInfo   info1  = new SysEventInfo("Info-1"); // catch all;
    SysEventInfo   info2  = new SysEventInfo("Info-2"); // catch specific class
    SysEventInfo   info3  = new SysEventInfo("Info-3"); // catch specific type
    ;
    // Setup
    broker.addListener(info1, classNum(Object));
    broker.addListener(info2, classNum(Runbase));
    broker.addListener(info3, classNum(Object), "Fire 2"); // catch Fire 2
    broker.addListener(info3, classNum(Object), "Fire 4"); // and Fire 4
 
    broker.fireEvent(classNum(CustAutoCreate), "Fire 1", "This is my life");
    broker.removeListener(info2, classNum(Runbase));
    broker.fireEvent(classNum(CustAutoCreate), "Fire 2", "this is my time");
    broker.fireEvent(classNum(CustAutoCreate), "Fire 3", "just show me the light");
    broker.removeListener(info1);
    broker.fireEvent(classNum(CustAutoCreate), "Fire 4", "and I go there");
}

Generated info:

Info-2 CustAutoCreate(Fire 1): This is my life
Info-1 CustAutoCreate(Fire 1): This is my life
Info-3 CustAutoCreate(Fire 2): this is my time
Info-1 CustAutoCreate(Fire 2): this is my time
Info-1 CustAutoCreate(Fire 3): just show me the light
Info-3 CustAutoCreate(Fire 4): and I go there

[edit] Explanation

An event broker and 3 event listeners are created. The event listeners are then registered with broker.addListener which takes 3 arguments:

  1. Listener object: identifying the listener object
  2. Class id: identifying the sender class which the listener is interested in
  3. Event type: an optional string identifying the event to listen to (all events if not given)

Then events are fired with broker.fireEvent which as parameter takes 3 arguments:

  1. Class id: identifying the sender class
  2. Event type: a string identifying the event
  3. data: any additional information which can have any type

In the first fireEvent the class id is SalesAutoCreate (it is a lie), the event type is "Fire 1" and the data is the first line of a song. As SalesAutoCreate has parent class RunBase and Object both info1 and info2 listeners receive the gotEvent call, and the first two lines of info is generated. The info3 listener does not get the event, it is interested in "Fire 2" and "Fire 4" events only.

It is unusual to have addListener and fireEvent in the same method. A more interesting way would be for a top level class to implement gotEvent, call addListener(this, classNum(SomeClass)), then deep down the call stack SomeClass will call fireEvent.

[edit] Global broker

Client classes need to share a SysEventBroker instance. A possible solution is to use the global Infolog object.

In the Info.classDeclaration add:

SysEventBroker eventBroker;

Add a new method:

public SysEventBroker eventBroker()
{
    if (!eventBroker)
        eventBroker = SysEventBroker::construct();
    return eventBroker;
}

Beware, Infolog lives at the client, all notified infomation is sent to the client.

You could make the same implementation in the Application class which lives at the server. But you must then remember to use the same broker.

[edit] Warning

This is no silver bullet, do not abuse!

  • Do not not use when standard method calls and argument passing is the easy solution.
  • Do not forget to unregister the listener, even if an exception is thrown. Use try/catch!
  • Registered listeners live as long as the broker, if it is Infolog.eventBroker() for the entire user session!

[edit] See also

Another solution on Issues concerning X++

Personal tools
Microsoft Community
Microsoft Dynamics Ax Community