AX7 – Wie Subscriptions und Events jetzt funktionieren
Ein weiteres Mal nutze ich mfp’s two cents als Quelle meiner Inspiration für einen Blogeintrag und gehe ein wenig in die Tiefe dessen, was er genannt hat. Er zeigte, wie eine Subscription aussehen kann und erklärte, dass durch die Attribut-basierte Vorgehensweise die Notwendigkeit wegfällt, den Herausgeber (Publisher) eines Event modifizieren zu müssen. Man musste in AX 2012 beispielsweise explizit ein Post-Event an einer Methode hinzufügen und dessen Properties verwenden, um zu definieren, welche Methode welcher Klasse der Abonnent (Subscriber) ist. Ich möchte u. a. aufzeigen, welche Typen von Events man jetzt abonnieren kann und wie einfach es ist, solche Abonnements / Subscriptions mit Visual Studio anzulegen und wie man bestehende aufspüren kann.
Warum man Events verwenden sollte
Auch falls dir der Nutzen von Eventing noch nicht klar sein sollte, möchte ich anmerken, dass bereits unter AX 2012 der erste und wichtigste ist, dass die Komplexität und letztendlich die Kosten von Upgrades niedrig gehalten werden können dadurch. Änderungen im und am Code müssen (zumindest potentiell) aufwendig gemerged werden, Subscriptions von Events eben nicht. Natürlich ist das eine leicht vereinfachte Darstellung der Umstände…
Zweitens wurden einige Änderungen an der Struktur der Applikation vorgenommen, die einen in manchen Situationen sogar dazu zwingen, Eventing einzusetzen. Ich gehe darauf in einem oder mehreren kommenden Beiträgen ein, das Stichwort in diesem Zusammenhang lautet Packages.
Event-Typen
In AX7 gibt es drei Typen von Events, die man abonnieren kann:
- Standard-Events
- Delegates
- Pre-/Post-Events
Standard-Events
Die größte Neuerung bringen die Events mit, die im Standard integriert wurden und die man bei vielen Objekttypen in Form der Events-Knoten im Designer antreffen kann. Microsoft hat jede Menge Standard-Events für die relevanten Ausführungszeitpunkte eingebaut. In AX 2012 musste man beispielsweise den die update()-Methode einer Tabelle anpassen oder zumindest ein Pre- oder Post-Event anfügen, um das Verhalten zu beeinflussen. Natürlich ist beides nach wie vor möglich, aber zusätzlich dazu gibt es zwei Events, die an jeder Tabelle vorhanden sind und die abonniert werden können, namentlich onUpdating() und onUpdated().
Delegates
Es gab schon bisher Delegates und sie sind auch noch immer vorhanden, aber die Art und Weise, wie man sie abonniert, hat sich geändert. Was sich so richtig geändert und auch fortlaufend erweitert wird (zumindest ist der Willen dazu bekundet worden), ist, dass Microsoft jetzt an geeigneten Stellen Delegates im Code platziert, um uns Eingriffe zu ermöglichen, ohne den Code verändern (customizen) zu müssen. Ein zufällig herausgegriffenes Beispiel könnte ein Delegate sein, der sich in der Klasse WmsLocationTreeBase befindet und ermöglicht, zum Zeitpunkt, wenn sie der Baum geändert hat, etwas anzufügen. Delegates können übrigens auch Parameter haben, um sinnvollerweise Kontext mitzugeben (oder gar ein Ergebnis wiederzuerlangen – by reference), sind aber immer void. Der Delegate ist wie folgt definiert und wird vom Standard-Code auch aufgerufen:
delegate void treeChanged() { }
Pre-/Post-Events
Man kann nach wie vor Pre- und Post-Events an Methoden anfügen. Es hat sich lediglich geändert, wie man das tut.
Events abonnieren und Subscriptions finden
Um ein neues Abonnement (eine neue Subscription) zu erstellen, kann man in allen drei Fällen im Designer einfach die Quelle des Events, also den Herausgeber / Publisher in Form von Standard-Event / Methode / Delegate, rechtsklicken und dann Copy event handler method anklicken. Dadurch wird der passende Code (mitsamt XML-Kommentar-Vorlage – Danke Microsoft!) für eine Subscription in die Zwischenablage kopiert. Jetzt muss man nur noch eine Event-Handler-Klasse erstellen (oder natürlich eine vorhandene verwenden) und einfügen. Für das onUpdated()-Event einer Tabelle mit Namen SomeTable sieht das wie folgt aus (außer dem Kommentar, mit dem hat mein Code-Formatter-Plugin Probleme):
[DataEventHandler(tableStr(SomeTable), DataEventType::Updated)] public static void SomeTable_onUpdated(Common sender, DataEventArgs e) { }
Wie man sehen kann, hat das Event bestimmte Attribute und Parameter, welche natürlich von Event-Typ zu Event-Typ unterschiedlich sein können.
Um bestehende Abonnements / Subscriptions finden zu können, muss man wiederum lediglich einen Rechtsklick auf den potentiellen Publisher machen und Find event handlers klicken. Alle Abonnenten werden dann umgehend im Bereich Find Symbol Results angezeigt.
Fallstricke
Du solltest dir die Reihenfolge der Ausführung bewusst machen, um da nicht in Schwierigkeiten zu geraten! Es gibt nämlich einen signifikanten Unterschied zwischen dem onUpdated()-Event und einem Post-Event der update()-Methode. Ich zeige das am besten einfach an einem kleinen Beispiel auf. Dazu nehmen wir eine Methode update() an, die wie folgt aussieht
public void update() { method1(); super(); method2(); }
und darüber hinaus über ein Pre- sowie ein Post-Event verfügen. Dabei ergibt sich die folgende Ausführungsreihenfolge:
- Pre-Event-Subscriptions
- method1();
- Subscriptions zu onUpdating()
- Aufruf von super()
- Subscriptions zu onUpdated()
- method2();
- Post-Event-Subscriptions
Das war’s für den Moment; ich hoffe, dass es hilfreich ist
*This post is locked for comments