24.01.2018, 17:21 | #1 |
Участник
|
D365 как правильно переопределить метод в таблице.
Добрый день.
По ходу изучения D365 возник вопрос. Как правильно переопределить метод в стандартной таблице. Пример: Нужно навесить метод insert на таблицу BankGroup. Таблица BankGroup - модель Application Suite. Свой проект я реальзовую на моей модели. В ней подключил модель Application Suite. Как я понимаю, данные кастомные вещи нужно делать через extension. правильно? Я создал BankGroup.Extension но добавить в него метод не могу. Что я не знаю и что делаю не правильно? |
|
24.01.2018, 18:51 | #3 |
Участник
|
Спасибо. С этим разобрался, да и видел подобные статьи. Теперь другое не получается реализовать. Например в 2012 в стандартные методы типа insert я мог добавить аргумент insert(int _i = 0).
Как сделать подобное в 365? |
|
24.01.2018, 21:28 | #4 |
Участник
|
Никак. И так же вы сможете передать новый параметр из существующего кода - никак. Остаётся способ передачи переменных через глобальный кеш или статические поля, но это уже на грани с извращением. Вы лучше задачу опишите.
Последний раз редактировалось skuull; 24.01.2018 в 21:32. |
|
25.01.2018, 00:20 | #5 |
Administrator
|
Цитата:
Теперь у нас есть события. Этих событий мы можем наплодить великое множество, гораздо больше, чем 2 варианта. Более того, мы в коде можем управлять последовательностью вызова обработчиков этих событий. Соответственно, теперь каждая логика будет иметь свой обработчик события insert(). Тут есть 3 варианта развития. Можно как-то внутри себя договориться и использовать единый обработчик insert-а (один класс) и в нем реализовывать все 100500 вариантов логики. Пример в прошлых версиях - класс InventUpdate и его наследники InventUpd_*. В нашем случае через GlobalCache можно будет создать единый инстанс этого обработчика и следить за этим. Минус такого подхода в том, что должен быть единый и постоянный архитектор, который за этим будет следить. Не все компании считают нужным содержать такого человека. Есть второй вариант, делать независимые обработчики и потом разгребать их конфликты в части порядка их вызова. Тут будет работать правило - кто последний, тому и сложнее. Ну и последний вариант - стараться отучать себя от программирования на insert/update/delete. Всегда можно найти способ этого не делать. Просто очень часто туда вставляют код, т.к. тяжело найти все те места в системе, которые могут вылезти уже после приема разработки. Но такой подход - лишь отсрочка этой проблемы, т.к. постепенно на insert / update / delete переползет вся бизнес-логика модификаций. Еще маленькое замечание - в целом неважно как "обрастет" код и насколько будет сложно его поддерживать. Конечно есть еще компании, у которых работает AX 3.0, но в большинстве своем жизненный цикл конкретной версии системы не настолько большой (лет 10), поэтому рано или поздно ее все равно будут менять и по сути перевнедрять, т.к. много воды уже утечет с момента первого внедрения. Причем что примечательно, что как раз-таки те компании, которые до сих пор сидят на 3.0 вероятнее всего не имеют и давно уже не имели того единого архитектора, который бы мог все контролировать. Так что плюс-минус неважно насколько "плохим" или "хорошим" со стороны окажется Ваше решение по выбору обходного пути. Соответственно прямой ответ на вопрос - никак, но есть разные обходные пути, которые могут решить исходную задачу иным способом.
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 25.01.2018 в 00:31. |
|
25.01.2018, 01:26 | #6 |
Banned
|
Цитата:
Virtual Field c "SaveContent" = No? Или завести поле .myParameters типа контейнер и грамотно класть и парсить через свой фрэйморк для этого. Я бы вообще такой контейнер добавил в .common А если серьезно то лучше забыть о таких задачах как "как правильно переопределить метод в таблице" в D365. Парадигма программирования изменилась. Только отсутствие связи или очень слабые связи, то есть или своя таблица или подписка на событие как отмашка. |
|
25.01.2018, 03:32 | #7 |
Участник
|
Я про это и говорил упоминая извращения. Непонятно что автор собираеться с этим параметром делать.
|
|
25.01.2018, 08:58 | #8 |
Участник
|
Вполне возможно, что автора устроит просто дополнительный extension method c дополнительной логикой и параметром - надо понять контекст.
|
|
25.01.2018, 11:04 | #9 |
Участник
|
Всем большое спасибо за ответы! На счет того, зачем и что я собираюсь делать с этим параметром отвечу: На данный момент я ознакамливаюсь и разбираюсь с D365. И захотел уяснить для себя этот вопрос, так как, правильно заметил sukhanchik, в 2012 привык вешать логику на insert / update / delete.
|
|
25.01.2018, 11:43 | #10 |
Участник
|
Как пример, для понимания, могу предложить следующую задачу синхронизации.
В CustTable добавляем свое enum:NoYes поле isSynch. Оно отображает синхронищзирована ли строка с другой системой. При insert CustTable поле isSynch=NoYes::No При update CustTable поле isSynch=NoYes::No Пускай есть обработчик синхронизации, он фильтрует CustTable по нашему полю и забирает не синхронизированые строки, делает update CustTable поле isSynch=NoYes::Yes В 2012 я бы добавил параметр и логику в метода update. Как мне поступить в D365? Может я по не опытности еще не придумал лучший вариант и не полностью разобрал ваши ответы, пока на ум приходит только один вариант реализации без этого аргумента. Делаем таблицу myTable с двумя полями. Enum::NoYes поле isSynch RefRecId поле CustTableRecId Связываем ее с CustTable. На insert CustTable вешаем создании соответственной строки и в моей новой таблице. на событие onUpdated CustTable вешаем myTable.isSynch = NoYes::No. А обработчик синхронизации будет lделать. myTable.isSynch = NoYes::Yes таком образом я избавляюсь от необходимости в аргументе на update. И, я заметил, в моих таблицах с методами insert/update/delete я могу работать как угодно, и добавлять параметры. Выходит, в соответствии с новыми парадигмами, в своих таблицах этого так же стоит избегать? |
|
25.01.2018, 12:49 | #11 |
Участник
|
Варианты:
1) Устанавливать в yes только если в update пришло новое значение Yes, иначе No. Проверять по orig() - новое или старое. 2) Тот, кто устанавливает факт синхронизации пользуется только doUpdate, а не update 3) Хранить состояние в отдельной таблице |
|
25.01.2018, 14:14 | #12 |
Участник
|
При событии обновления обновлять себя же - плохая идея. Во-первых, это рождает запутанный код, а во-вторых, возможны непредвиденные ошибки при не слишком глубоких знаниях разработчика. По мне так лучше
__________________
// no comments |
|
25.01.2018, 15:24 | #13 |
Banned
|
Цитата:
Сообщение от Skolos
Как пример, для понимания, могу предложить следующую задачу синхронизации.
... И, я заметил, в моих таблицах с методами insert/update/delete я могу работать как угодно, и добавлять параметры. Выходит, в соответствии с новыми парадигмами, в своих таблицах этого так же стоит избегать? Если нужно "run-time" то postInsert подписка с хранением состояния в отдельной таблице. |
|
25.01.2018, 22:12 | #14 |
Administrator
|
Цитата:
Сообщение от Skolos
Может я по не опытности еще не придумал лучший вариант и не полностью разобрал ваши ответы, пока на ум приходит только один вариант реализации без этого аргумента.
Делаем таблицу myTable с двумя полями. Enum::NoYes поле isSynch RefRecId поле CustTableRecId Связываем ее с CustTable. На insert CustTable вешаем создании соответственной строки и в моей новой таблице. на событие onUpdated CustTable вешаем myTable.isSynch = NoYes::No. А обработчик синхронизации будет lделать. myTable.isSynch = NoYes::Yes таком образом я избавляюсь от необходимости в аргументе на update. Вариант с myTable - хороший вариант. Более того, дополнительное поле isSynch даже не нужно. Его роль будет играть наличие записи в myTable. Собственно говоря событие update() тут и не нужно. Приходит обработчик синхронизации, забирает записи из CustTable и вставляет забранные RecId в отдельную таблицу. Это событие (с т.з. бизнес-пользователя) никак не связано с изменением какого-либо другого поля типа "Налоговая группа" непосредственно в CustTable. Отобразить галку в CustTable можно с помощью дисплей-метода, который будет делать exists join к myTable. Фильтровать - также по (not) exists join (тут придется немного покодить, если захочется организовать пользователю фильтр по этому полю, однако задача глобально - решаема). Так что в контексте этой задачи использовать методы insert / update для вставки своей логики - не нужно. В отношении delete, если реализовать каскадное удаление в myTable, то на delete в myTable можно будет послать какой-нибудь сигнал второй системе. Но это уже не на CustTable, а в myTable - т.о. штатный функционал не трогается. Цитата:
Поэтому на мой взгляд лучше избегать использования insert / update / delete, чтобы впоследствии не пришлось бы управлять последовательностью вызова многочисленной толпы обработчиков insert / update / delete. Ряд задач может решиться с помощью дополнительных узкоспециализированных таблиц.
__________________
Возможно сделать все. Вопрос времени |
|
|
За это сообщение автора поблагодарили: ax_mct (3), Skolos (1). |
25.01.2018, 23:12 | #15 |
Banned
|
Цитата:
Сообщение от Skolos
Всем большое спасибо за ответы! На счет того, зачем и что я собираюсь делать с этим параметром отвечу: На данный момент я ознакамливаюсь и разбираюсь с D365. И захотел уяснить для себя этот вопрос, так как, правильно заметил sukhanchik, в 2012 привык вешать логику на insert / update / delete.
Microsoft об этом не говорит, выставляя дырки и хуки, но про себя подразумевает. А мы по инерции рассматриваем D365FoE только как изменение приемов и техники программирования. И это засада. |
|
30.01.2018, 12:24 | #16 |
Участник
|
Еще извращений с изменением сигнатуры метода от ведущих умов https://blogs.msdn.microsoft.com/mfp...od-signatures/
|
|
|
За это сообщение автора поблагодарили: Vadik (1), ax_mct (3). |
30.01.2018, 12:28 | #17 |
Модератор
|
Цитата:
Сообщение от skuull
Еще извращений с изменением сигнатуры метода от ведущих умов https://blogs.msdn.microsoft.com/mfp...od-signatures/
__________________
-ТСЯ или -ТЬСЯ ? |
|
30.01.2018, 22:01 | #18 |
Banned
|
Цитата:
Сообщение от skuull
Еще извращений с изменением сигнатуры метода от ведущих умов https://blogs.msdn.microsoft.com/mfp...od-signatures/
Как обычно самое интересное в комментариях. 1. Конечный клиент это клиент компании Microsoft. 2. Microsoft работает с конечными клиентами напрямую. 3. Цель Microsoft - обновлять систему технически и функционально когда и как он захочет. 4. Ответственность за совместимость на вас как ISV, Партнера или клиента. Вы все еще хотите переопределять метод в таблице D365FoE в чужом приложении для чужого клиента? Главное это понять парадигму "the ‘open-close’ paradigm .. Open for extensions, closed for modifications". Это главнее чем нахождение форточки. И об этой парадигме как-то все молчат, а в ней вся соль. Цитата:
Michael Fruergaard Pontoppidan
January 19, 2018 at 8:10 am Thanks Dick. The overall goal of extensibility is to get our shared customer running on the latest release always. This means that extra care and attention to writing robust extensions are required. Significantly more care than when customizing via overlayering. Ultimately; we want to be able to do a binary replace of AppSuite – and everything still works. The AX extensibility model is quite powerful – too powerful in some cases. When using this toolbox, you are responsible for building a solution that can “survive” an AppSuite upgrade as-is. Any brittleness you build in, like dependencies on call stack, extensions to methods that are not coherent with the standard method will cause disruption to our customers. One example of the latter is to change the global company context in an extension method. We trust you to make strong, durable and lasting solutions. I agree there is a turn-around time on extension requests; which can be obstructive to development. The sooner you log them the sooner you’ll get them; plan for this delay. Regarding option 2: The state is class instance specific – not global. There are cases where the state is coherent with the class and its purpose. Here I would not have concerns. Regarding option 3: You should really use IDisposable, like outlined, instead of guids and potentially stale caches. Regarding delegates: Chain-of-command is large replacing the need for delegates (and requests for adding these). |
|
31.01.2018, 10:25 | #19 |
Moderator
|
Цитата:
Похоже что идеологи нового подхода просто не представляли насколько дорого ободится сервисная сторона внедрений, и предпологали что хотя микрософт будет работать напрямую с клиентами, управление мешающимися под ногами партнерами не будет слишком дорого обходится. На практике все конечно оказалось не так, реалистичных бюджетов на управление партнерами и проектами внедрения у MS конечно нету (конечно за исключением тех немногих проектов, которые ведутся MCS). Поэтому эта идея насчет того что микрософт работает с клиентом напрямую на практике потихонечку умирает (просто явочным порядком - поскольку ни у кого в MS нету времени вести наши проекты напрямую и при этом еще как-то нас воспитывать). А MFP просто очень удален от реальности и до него эта интересная информация пока не дошла... |
|
|
За это сообщение автора поблагодарили: Vadik (1). |
31.01.2018, 18:57 | #20 |
Banned
|
Создал тему здесь
Эко-система Microsoft, это как? Последний раз редактировалось sukhanchik; 01.02.2018 в 09:17. |
|
|
|