Event Handling in X++

When you are writing code in C# you can create events and define delegate methods that will be called when the event is triggered. Unfortunately, this is not implemented in the X++ language.
I have read some nice posts about how eventing is implemented in .NET and about the design patterns used (observer, …) and decided to build this myself.
The method I used is using the observer pattern and lets you subscribe to an eventhandler object that can be defined on a class you want to monitor. It is actually quite simple, but can come in handy when available.
Note : Don’t mind the HEL prefix, this is just a prefix used for some tools here. And also, some objects can be extended with additional functionality to contain more information, …
First I created an HELEventHandler class which contains a map with registered listener objects. The methods attachListener and removeListener can be used to register / deregister an object method to listen for the event. The validateListener performs some checks to see if the callback method has the right structure. The fireEvent method is responsible to notify all the listeners of the event triggered.
The HELEventArguments class is created just to pass it when the event is fired. For now, this is an empty shell, but can be extended / adjusted to contain extra information on the fired event.
Now let’s see how we can put this to work. First we start by create a class for testing:HELTestClassEvent. We have a name member here and an eventhandler member.
class HELTestClassEvent
{
    Name mName;
    HELIEventHandler mNameChangedEventHandler;
}
The eventhandler is made public by adding a parameter method.
public HELIEventHandler parmNameChangedEventHandler(HELIEventHandler _nameChangedEventHandler = mNameChangedEventHandler)
{
    ;
    mNameChangedEventHandler = _nameChangedEventHandler;
    return mNameChangedEventHandler;
}
Now let’s say we want an event that is triggered when the name changes. Then we would like to add a method that can be called to notify that the name has changed.
private void onNameChanged(Object _sender, HELEventArguments _arguments)
{
    ;
    if(this.parmNameChangedEventHandler())
    {
        this.parmNameChangedEventHandler().fireEvent(_sender, _arguments);
    }
}
And this will be called like this :
void run()
{
    ;
    mName = "Kenny";
 
    this.onNameChanged(this, new HELEventArguments());
 
    info("I did my work");
}
For now, we have everything we need to let an object notify others that an event has happened. Now we will take a look at how we can register other objects to listen to this event. Let’s create an extra class that will be notified. There, we will first need to create a method that will do the actual work when the event is fired.
public void HELTestClassEvent_OnNameChanged(Object _sender, HELEventArguments _eventArgs)
{
    ;
    info("Who changed the name ?!");
}
And last but not least we actually attach this method to the event by doing this:
void run()
{
    HELTestClassEvent test = HELTestClassEvent::construct();
    ;
 
    // We want to attach a method of this class to the event that the name is changed in the HELTestClassEvent object
    test.parmNameChangedEventHandler(HELEventHandler::construct());
    test.parmNameChangedEventHandler().attachListener(this, methodStr(HELTestClassEventCalledBack, HELTestClassEvent_OnNameChanged));
 
    // Run the HELTestClassEvent object
    test.run();
}

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.