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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 07.11.2018, 15:54   #1  
malex is offline
malex
Участник
 
163 / 14 (1) ++
Регистрация: 10.08.2004
Адрес: Тверь, Москва
? D365FO: Inheritance + Extensions + RealTime
Есть 8.0 PU15. Переношу overlaid-решение на extensions.

В классе InventMovement был кастом-метод, который был перекрыт в наследниках (InventMov_Purch)
Я создал extensions к этим методам и ожидаю, что в real-time вызовется нужный extension:
X++:
[ExtensionOf(classStr(InventMovement))]
final class InventMovementAQM_Extension
{
    boolean AQMmustUpdateBatchInfo()
    {
        return false;
    }
}

[ExtensionOf(classStr(InventMov_Purch))]
final class InventMov_PurchAQM_Extension
{
    boolean AQMmustUpdateBatchInfo()
    {
        return true;
    }

}
Вызов (COC):
X++:
[ExtensionOf(tableStr(InventBatch))]
final class InventBatchAQM_Extension
{
    public void initFromInventMovement(InventMovement _inventMovement, InventTrans _inventTrans)
    {
        next initFromInventMovement(_inventMovement, _inventTrans);

        if (_inventMovement.AQMmustUpdateBatchInfo())
        {
            // blablabla
        }
    }
В realtime передаю в _inventMovement InventMov_Purch и ожидаю, что вызовется AQMmustUpdateBatchInfo() у экстеншена InventMov_PurchAQM_Extension. Однако вызов происходит у InventMovementAQM_Extension (параметр объявлен как InventMovement)

Если сделать явное преобразование
X++:
InventMov_Purch invMov;
        invMov = _inventMovement;
        if (invMov.AQMmustUpdateBatchInfo())
        {
        }
То будет вызов как я ожидаю.

Как Вы считаете - это баг? В 8.1\8.1.1\8.1.2 система ведет себя также?
Старый 07.11.2018, 17:11   #2  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
495 / 232 (8) ++++++
Регистрация: 27.04.2006
Адрес: Montreal
Wrapping a base method in an extension of a derived class
The following example shows how to wrap a base method in an extension of a derived class. For this example, the following class hierarchy is used.


X++:
class A
{
    public void salute(str message)
    {   
        info(message);
    }
}

class B extends A {}
class C extends A {}
Therefore, there is one base class, A. Two classes, B and C, are derived from A. We will augment or create an extension class of one of the derived classes (in this case, B), as shown here.


X++:
[ExtensionOf(classStr(B))]
final class B_Extension
{
    public void salute(str message)
    {
        next salute(message);
        info("B extension");
    }
}
Although the B_Extension class is an extension of B, and B doesn't have a method definition for the salute method, you can wrap the salute method that is defined in the base class, A. Therefore, only instances of the B class will include the wrapping of the salute method. Instances of the A and C classes will never call the wrapper method that is defined in the extension of the B class.

This behavior becomes clearer if we implement a method that uses these three classes.

X++:
class ProgramTest 
{
    public static void main(Args args)
    {
        var a = new A();
        var b = new B();
        var c = new C();

        a.salute("Hi");
        b.salute("Hi");
        c.salute("Hi");
    }
}
For calls to a.salute(“Hi”) and c.salute(“Hi”), the Infolog shows only the message “Hi.” However, when b.salute(“Hi”) is called, the Infolog shows “Hi” followed by “B extension.”

By using this mechanism, you can wrap the original method only for specific derived classes.

https://docs.microsoft.com/en-us/dyn...d-wrapping-coc
__________________
Felix nihil admirari
-----------------------------------------------------------------------------------------------
AX2012

Последний раз редактировалось wojzeh; 07.11.2018 в 17:13.
Старый 07.11.2018, 18:30   #3  
malex is offline
malex
Участник
 
163 / 14 (1) ++
Регистрация: 10.08.2004
Адрес: Тверь, Москва
?
Цитата:
Сообщение от wojzeh Посмотреть сообщение
Wrapping a base method in an extension of a derived class
The following example shows how to wrap a base method in an extension of a derived class. For this example, the following class hierarchy is used:
Здравствуйте, wojzeh. Спасибо за ответ. У меня немного другая ситуация: у меня нет COC, но есть extension для базового класса и extension для наследника. Если переменная объявлена как базовый класс, но в realTime инициализируется как наследник, то extension все равно вызывается для базового класса.
(Thank you for your answer. I have the different case: I havn't COC. I have extensions for parent class and for a child. Both extensions has the same method. A class variable declared as a parent class, but initialized as a child. The system invokes extension for the parent class)
X++:
class A
{
}
class B extends A
{
}
[ExtensionOf(classStr(A))]
final class A_Extension
{
    public void salute()
    {
        info("A extension");
    }

}
[ExtensionOf(classStr(B))]
final class B_Extension
{
    public void salute()
    {
        info("B extension");
    }

}
X++:
class Test01
{        
    public static void main(Args _args)
    {    
        A a;

        a = new B(); 

        a.salute();
    }

}
В результате получим "A extension".
За это сообщение автора поблагодарили: Pokersky09 (2).
Старый 07.11.2018, 21:50   #4  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
495 / 232 (8) ++++++
Регистрация: 27.04.2006
Адрес: Montreal
технически у тебя два разных класса: исходный и его расширения. очевидно невозможно перекрывать методы расширений (они ж final) ни в классах наследниках, ни в их, наследниках, расширениях. поэтому, строго говоря, это вообще два разных метода у тебя, несмотря на то, что имена у них одинаковы.

если бы расширение класса-наследника "видело" все добавленные во всех расширениях методы класса-родителя, то потребовалось бы вызывать next. и наоборот, если бы расширенные методы класса-родителя трактовались как "родные", они были бы доступны к перекрытию, но ты не можешь вызвать super во втором методе.

так что IS и AS твои друзья тут
__________________
Felix nihil admirari
-----------------------------------------------------------------------------------------------
AX2012
За это сообщение автора поблагодарили: trud (2), malex (1), ax_mct (3).
Старый 08.11.2018, 09:44   #5  
malex is offline
malex
Участник
 
163 / 14 (1) ++
Регистрация: 10.08.2004
Адрес: Тверь, Москва
Post
Цитата:
Сообщение от wojzeh Посмотреть сообщение
так что IS и AS твои друзья тут
Я так и поступил, но надеялся что это был workaround. Придется почти весь код из наследников переносить в родительский классы с кучей кейсов.

PS: Я все таки думал что на уровне своих методов в экстеншенах будет наследование. А то получается мы у себя в МС будем использовать наследование и override, а вы со своими ISV решениями мучайтесь как хотите и плевать что архитектура внутри у вас будет не очень и с кучей дублирования кода.

Последний раз редактировалось malex; 08.11.2018 в 09:46.
Старый 08.11.2018, 10:51   #6  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,334 / 4396 (151) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Цитата:
Сообщение от malex Посмотреть сообщение
Я так и поступил, но надеялся что это был workaround. Придется почти весь код из наследников переносить в родительский классы с кучей кейсов.

PS: Я все таки думал что на уровне своих методов в экстеншенах будет наследование. А то получается мы у себя в МС будем использовать наследование и override, а вы со своими ISV решениями мучайтесь как хотите и плевать что архитектура внутри у вас будет не очень и с кучей дублирования кода.
А не думали над таким подходом:
1. Определить свои классы как наследники inventMov_purch, inventMov_Sales и тп
2. Переопределить с помощью CoC метод inventMovement::constructNoThrow(), так чтобы он возвращал экземпляры своих классов, вместо стандартных ?
Старый 08.11.2018, 12:14   #7  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,221 / 2410 (89) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
Может я глупость скажу, но в исходном примере final class InventMovementAQM_Extension то есть эктеншены это два не связанных между собою типа и добавляют два несвязанных между собой метода. Вы пробовали унаследовать один от другого?
__________________
https://axcoder.github.io
Старый 12.11.2018, 23:31   #8  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
495 / 232 (8) ++++++
Регистрация: 27.04.2006
Адрес: Montreal
Макс, это не глупость, а именно то же, что уже сказал я. Раз нас уже двое, то мы не можем ошибаться!
__________________
Felix nihil admirari
-----------------------------------------------------------------------------------------------
AX2012
Старый 13.11.2018, 04:14   #9  
ax_mct is offline
ax_mct
Участник
Аватар для ax_mct
 
2,135 / 832 (32) +++++++
Регистрация: 10.10.2005
Адрес: Westlands
Тут кстати есть где сконфьюзиться
Цитата:
the classes that inherit from a class that has extensions inherit the methods that are defined in the extension classes.
https://docs.microsoft.com/en-us/dyn...ass-extensions

Концепция эффективного класса. Причем эта "сборка" еще зависит от включенных моделей. Как я понимаю extension это не про "extend", а про "add".

The effective class concept


Старый 13.11.2018, 04:19   #10  
ax_mct is offline
ax_mct
Участник
Аватар для ax_mct
 
2,135 / 832 (32) +++++++
Регистрация: 10.10.2005
Адрес: Westlands
Важно что это на самом деле class augmentation (приращение) просто они для красного словца используют class extension
Цитата:
The functionality for class extension, or class augmentation,
Старый 13.11.2018, 11:33   #11  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,221 / 2410 (89) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
Цитата:
Сообщение от wojzeh Посмотреть сообщение
Макс, это не глупость, а именно то же, что уже сказал я. Раз нас уже двое, то мы не можем ошибаться!
Я имел ввиду, что, может, достаточно сделать их наследниками (но, соответственно, получается что от фреймворка требуется соблюдения правила что подкласс вытесняет суперкласс из экстешненов, а соблюдается ли оно, я не знаю)
__________________
https://axcoder.github.io
Старый 19.11.2018, 21:15   #12  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
495 / 232 (8) ++++++
Регистрация: 27.04.2006
Адрес: Montreal
как это ты их сделаешь наследниками?
__________________
Felix nihil admirari
-----------------------------------------------------------------------------------------------
AX2012
Старый 20.11.2018, 15:08   #13  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,221 / 2410 (89) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
Цитата:
Сообщение от wojzeh Посмотреть сообщение
как это ты их сделаешь наследниками?
Вернее, одного вылечить от бездетности, а второго сделать наследником.

X++:
// remove "final"
class InventMovementAQM_Extension
...

// add "extends"
final class InventMov_PurchAQM_Extension extends InventMovementAQM_Extension
...
__________________
https://axcoder.github.io

Последний раз редактировалось belugin; 20.11.2018 в 15:09. Причина: Запятые - это важно!
Старый 21.11.2018, 00:52   #14  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
495 / 232 (8) ++++++
Регистрация: 27.04.2006
Адрес: Montreal
ух ты! а вот у этого, второго, который не стрелял, у него на шапке звезда горит и написано [ExtensionOf(?)] ?
__________________
Felix nihil admirari
-----------------------------------------------------------------------------------------------
AX2012
Старый 21.11.2018, 09:45   #15  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,221 / 2410 (89) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
Ну да. Сам не пробовал, но интересно, что получится.
__________________
https://axcoder.github.io
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
erconsult: Copy-paste with keyboard script 2: from Excel to D365FO Blog bot DAX Blogs 0 03.08.2018 11:12
daxmusings: The Overall Concept of Extensions in AX 7 Blog bot DAX Blogs 0 14.09.2017 13:11
sertandev: AX7 Extensibility Overview – Part 2 : Code extensions Blog bot DAX Blogs 0 28.08.2017 19:11
daxmusings: The Overall Concept of Extensions in AX 7 Blog bot DAX Blogs 0 04.10.2016 12:11
goshoom: Class extensions Blog bot DAX Blogs 0 18.07.2016 17:11
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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