AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX Blogs
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 28.08.2017, 19:11   #1  
Blog bot is offline
Blog bot
Участник
 
25,459 / 846 (79) +++++++
Регистрация: 28.10.2006
sertandev: AX7 Extensibility – Part 3 : Event handlers and delegates (hooks)
Источник: https://sertandev.wordpress.com/2017...legates-hooks/
==============

In the previous blog post we had a look at the possibilities of adding new methods and variables to existing AX7 program code using extensions. What if we need to modify, or add extra functionality to existing methods or events on existing classes, tables and forms? In that case we use AX7 events and delegates (also called ‘hooks’).

There are already plenty of events (hooks) we can subscribe in AX and extend the existing functionality without overlayering or overriding the function we need to extend. You can find those under the “Events” node of the application objects. Subscription is as easy as right clicking and selecting “Copy event handler method”, then you need to paste it into an eventhandler class and write your own logic inside:

public static class ExtensionDemoInventTableEventHandlers{[DataEventHandler(tableStr(InventTable), DataEventType::Deleted)]public static void InventTable_onDeleted(Common sender, DataEventArgs e){ InventTable inventTable = sender as InventTable;//Your logic}}Here I have subscribed to the ‘Deleted’ event of the table. Note that the object methods (like insert, update, init, write..) we used to override in the AX 2012 now corresponds to two different events, as ‘Deleting’ and ‘Deleted’, and we no more call super() in our event handler methods. The execution of those compared to AX2012 works like below:

public void delete(){.... //Existing code before superEvent_onDeleting();super();Event_onDeleted();.... //Existing code after super}As a good practice you can place those event handlers in a static class which you suffix with ‘EventHandlers’ (which is not mandatory), or inside the extension class you have created for that object. On all events you subscribe you also have a parameter that contains an “event args” object for the corresponding event. However this parameter is not always the event args class you exactly need.. They are generally downcasted to their most common base class (DataEventArgs for data related events or FormEventArgs for events on the form root) and you need to cast it back to the args class you need. See the validatedFieldValue eventhandler below as an example :

[DataEventHandler(tableStr(InventTable), DataEventType::ValidatedFieldValue)]public static void InventTable_onValidatedFieldValue(Common sender, DataEventArgs e){ InventTable inventTable = sender as InventTable; ValidateFieldValueEventArgs ve = e as ValidateFieldValueEventArgs; boolean ret = ve.parmValidateResult(); if(ret) { switch(ve.parmFieldName()) { case fieldStr(InventTable,Description5): if(InventTable.Description5=="") { ret = false; } break; } }ve.parmValidateResult(ret);}

There are a lot of event handlers with downcasted parameters like this one and it is impossible to list all of them here. You can investigate existing code for that and I recommend you to create yourself a template document with templates to cast the Args parameters or reach other objects using the args or “sender” parameters within the eventhandler (if I grow one, i will share it here).

Beyond these events listed inside the Events node, there are Pre and Post event handlers which you can subscribe to existing public methods, and run your own logic before or after the original method is executed. And it is possible to change the return type and access the method parameters using the XppPrePostEventArgs parameter like the example below:

[PreHandlerFor(tableStr(InventTable), tableMethodStr(InventTable, defaultField))]public static void InventTable_Pre_defaultField(XppPrePostArgs args){ InventTable inventTable = Args.getThis() as InventTable; FieldId parmFieldId = Args.getArg('_fieldId'); switch(parmFieldId) { case fieldNum(InventTable, Description5) : InventTable.Description5 = ''; break; }}[PostHandlerFor(tableStr(InventTable), tableMethodStr(InventTable, isBOMAllowed))]public static void InventTable_Post_isBOMAllowed(XppPrePostArgs args){ InventTable inventTable = Args.getThis() as InventTable; boolean ret = Args.getReturnValue(); if(ret) { ret = (inventtable.Description5 != ""); }Args.setReturnValue(ret);}By default, you cannot subscribe to protected or private methods, but there is a workaround to be able to subscribe those. You can customize the object that holds the method by overlayering and add the following attribute on top of the method. Then you will be able to add pre and post handlers to that method regardless of protected or private modifier :

[HookableAttribute(true)]protected boolean parmHasArgs(boolean _hasArgs = hasArgs){ hasArgs = _hasArgs; return hasArgs;}To be able to query existing eventhandlers one event has, simply right click and select “Find event handlers” :



We have seen how to use existing events and how to add extended code before or after a method call. What if we need to modify a method by inserting program code in the middle of its program code? In that case we use delegate methods just as in AX2012. Subscribing to a delegate function is as shown below:



Then paste it into your extension, or event handler class:

[SubscribesTo(classStr(LedgerJournalCheckPost), delegateStr(LedgerJournalCheckPost, runInternalPostPostJournalDelegate))] public static void LedgerJournalCheckPost_runInternalPostPostJournalDelegate(LedgerJournalCheckPost _ledgerJournalCheckPost, boolean _postingSuccess, boolean _intercompanyPostingSuccess) { //Your own logic }There are already many delegate functions in key classes published by Microsoft and we can add new ones by overlayering these classes ourselves. If you do not want to use overlayering, in the time of writing, there is an option to book a request in Microsoft in Visual Studio Online and ask them to add a delegate to a system method for you, which is not accessible for everyone (I think only for the companies in the development program). You can ask your administration if this is available for your company. If you would like to create a delegate in your own code to allow subscription, you declare it like below. Then from the designer window of your class you can subscribe to your own delegate:

class ExtensionDemoDelegateTest{void new(){}public void showMessages(){Description message='Internal message text';info('Before..');this.showMessageText(Message);info('After...');}delegate void showMessageText(Description _msg) {}public static void main(Args _args){ExtensionDemoDelegateTest test;test = new ExtensionDemoDelegateTest();test.showMessages();}}

static class ExtensionDemoDelegateTestEventHandlers{//Handler 1[SubscribesTo(classStr(ExtensionDemoDelegateTest), delegateStr(ExtensionDemoDelegateTest, showMessageText))]public static void ExtensionDemoDelegateTest_showMessageText(Description _msg){info('Message echo from the event handler: '+_msg);}//Handler2[SubscribesTo(classStr(ExtensionDemoDelegateTest), delegateStr(ExtensionDemoDelegateTest, showMessageText))]public static void ExtensionDemoDelegateTest_showMessageText2(Description _msg){info('Message echo from the event handler 2: '+_msg);}}When we run the class :



As you see we can add as much hooks (or eventhandlers) as we want and they will run when the delegate is called inside the class method. Remember in AX, just like .NET, there is no guarantee on execution order of the eventhandlers subscribed to a delegate method. So never assume in your code that the first eventhandler you write will execute before the second or so, that is not guaranteed.

That is all about the event handlers in this blog. For more information on event handlers and delegates, you can check the wiki articles at :

https://ax.help.dynamics.com/en/wiki...y-and-keywords

https://ax.help.dynamics.com/en/wiki...and-extensions




Источник: https://sertandev.wordpress.com/2017...legates-hooks/
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
SysDictCoder: Performance considerations: event handlers Blog bot DAX Blogs 0 04.12.2015 17:11
X++: How to use X++ Delegates in Dynamics AX 2012 Blog bot DAX Blogs 0 03.08.2011 09:11
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 00:44.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.