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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 01.06.2017, 14:22   #81  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
И чтобы закрыть темы, прозвучавшие в этой ветке.
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
передача параметров здесь не предусмотрена "в принципе". Все "параметры" поднимаются из unpack уже "потом". После инициализации

...

Собственно, сделайте поиск по перекрестным ссылкам, где используется хотя бы classfactory.createClass() не говоря уже о DictClass.makeObject(). Удивитесь как много подобных вызовов

Поэтому, чтобы не получить проблему "на ровном месте" в среде Axapta следует жестко придерживаться правила

Никаких параметров в методах new

Да, в большинстве случаев, у Вас проблем не будет, если Вы передадите параметр в new. Но однажды, в самый неподходящий момент, все "вдруг" перестанет работать
Нет. По факту это не так. Уж не знаю, к счастью или к сожалению.
И параметры в new вполне предусмотрены (я не знаю почему только 5 параметров),
и сам фреймворк, заменяющий технологию конструкторов, использует конструкторы...
Но пост мне очень понравился.
Поскольку проблема действительно была. Не знаю осталась ли она сейчас. Надо полагать, исправили.

https://www.facebook.com/photosm/pho...type=3&theater
Миниатюры
Нажмите на изображение для увеличения
Название: 1.PNG
Просмотров: 274
Размер:	35.5 Кб
ID:	11458   Нажмите на изображение для увеличения
Название: 2.PNG
Просмотров: 230
Размер:	46.1 Кб
ID:	11459  

__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 01.06.2017 в 14:43.
Старый 01.06.2017, 15:08   #82  
ax_mct is offline
ax_mct
Banned
 
2,548 / 1091 (0) ++++++++
Регистрация: 10.10.2005
Адрес: Westlands
Охренеть. Switch case 1, 2, 3, 4, 5. Наверное когда додумаются передавать массив параметров (array[]) тогда оформят это патентом.
Старый 01.06.2017, 19:07   #83  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от ax_mct Посмотреть сообщение
Охренеть. Switch case 1, 2, 3, 4, 5. Наверное когда додумаются передавать массив параметров (array[]) тогда оформят это патентом.
Не получится. Здесь безвыходная ситуация. Ведь надо передать параметр в метод new класса, о котором вообще ничего не известно! Чтобы передать как массив или объект надо быть твердо уверенным, что создаваемый экземпляр класса именно как массив или объект эти самые параметры и принимает.

Тут более занимательный вопрос, а откуда эти самые параметры вообще взялись-то? Если "знают" какие параметры передавать, то должны и "знать" о каком классе идет речь. Тогда DictClass.makeObject() становится как-то неуместным. Проще уж собственно экземпляр класса создать и его использовать. Зачем явно лишняя "прослойка"
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...

Последний раз редактировалось Владимир Максимов; 01.06.2017 в 19:10.
Старый 01.06.2017, 19:32   #84  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Эпиграф 1:
- Перебилдь
- Сам ты Перебилдь

Эпиграф 2:
Пока течет мой любимый кетчуп билдится мой любимый Retail...


для начала ссылка на прошлый проект с традиционными construct:
Цитата:
Сообщение от mazzy Посмотреть сообщение
например, вот такой проектик.
собрал на коленке по-старому пока билдится этот ритейл, блин.
...

==============================
состав проекта:

==============================
Disclimer:
...
теперь новый проект на атрибутах.
как и в прошлом проекте, я постарался сделать качественно и кратко настолько насколько это возможно. но при этом использовать только штатные средства, которые входят в текущую поставку.

время на этом проекте конечно не показатель, поскольку сейчас много куда смотреть пришлось. но занимался я им 4-5 перебилдов и пару передеплоев ритейла - часа 4. следующие подобные проекты можно выполнять за те же 10-15 минут.

логика поведения Аксаптовских объектов вывернута наизнанку. Например, стандартно menuItem указывает на объект. А в фреймворке наоборот, к объекту привязывается menuItem, а в menuItem указыается клаcc запускач. И так во всем фреймворке.

да, я сейчас написал так, что перекрестные ссылки на все объекты есть. но и их логика вывернута.
да, очень велика вероятность того, что вместо classstr, menuItemActionStr программисты будут тупо использовать простые строки и перекрестных ссылок не будет в принципе.
да, всегда остается возможность поиска подстроки с названием объекта... но очень боюсь, что и они будут составными и ненаходимыми.

ну, и, конечно, все ушло в рантайм.
конечно, да, рантайм дает позднее связывание.
но контроль на этапе компиляции - это контроль на этапе компиляции.

и сообщения в рантайм "неправильное использование функции" без информации какие именно аргументы были у этой функции - это прекрасно!
и вы будете ржать, то однажды выполнившись на АОС, атрибут-класс кэшируется, если код изменить неправильно (неуникальное или несуществующее значение артрибута, например) то оно будет выполнять исходя из закешированных значений атрибутов.
или я полностью не понимаю происходящее.
но уверен, что ЭТО прекрасно!

и пока совершенно не понимаю, как ЭТО покрывать тестами.
и пока не могу найти примеров в существующем коде, чтобы ЭТО было покрыто тестами.
надо подумать.

=============================
суть проекта:
main() перенесен в отдельный класс-запускач.
логика всех конструкторов размазана по атрибутам и main() в запускаче.
у классов потомков проставлены атрибуты, привязанные к menuItem
для всех запускаемых классов есть свой menuItem
все релевантные menuItem переброшены на класс-запускач

=============================
кажется, что логика запуска стала проще.
но это только потому что это такая безумная реализация в данном примере - обычно никто не делает переключение логики при помощи parm в меню итеме.

обычно, логика запуска класса должна быть более изощренна.
следовательно, будет более запутана - часть в атрибутах, часть в коде, который готовит ключи на основании параметров, датасорсов и caller...

опять же - получается совершенно вывернутая логика.
раньше логика запуска была размазана по конструкторам - каждый отвечал за свой уровень в иерархии.

теперь логика запуска размазана по атрибутам и одновременно сконцентрирована в main().
я пока не очень понимаю что будет если разные партнеры расширят семейство классов каждый по своему, а потом заказчик должен будет эти расширения объединить в одном main.
возможно, можно как-то комбинировать стратегии.

===============================
ну, и строка-ключ с позиционными данными и с разделителем ;
это пипец, товарищи.

===============================
на скриншотах циферки:
1. нужно указывать базовый класс
2. нужно делать cast. для этого нужно знать к какому базовому классу кастить. в семействе может быть несколько базовых с разной логикой. см FormLetter.
3. перекрестные ссылки с базового класса CustVendAutoDialog_RU - да, если писать правильно, то перекрестные ссылки есть
Миниатюры
Нажмите на изображение для увеличения
Название: 01.PNG
Просмотров: 278
Размер:	92.2 Кб
ID:	11461   Нажмите на изображение для увеличения
Название: 02.PNG
Просмотров: 234
Размер:	99.8 Кб
ID:	11462  

Нажмите на изображение для увеличения
Название: 03.PNG
Просмотров: 291
Размер:	80.7 Кб
ID:	11463   Нажмите на изображение для увеличения
Название: 04.PNG
Просмотров: 244
Размер:	62.7 Кб
ID:	11464  

Нажмите на изображение для увеличения
Название: 05.PNG
Просмотров: 223
Размер:	28.2 Кб
ID:	11465   Нажмите на изображение для увеличения
Название: 06.PNG
Просмотров: 273
Размер:	116.4 Кб
ID:	11466  

Нажмите на изображение для увеличения
Название: 07.PNG
Просмотров: 206
Размер:	52.4 Кб
ID:	11467  
Вложения
Тип файла: axpp bb.axpp (9.6 Кб, 78 просмотров)
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 01.06.2017 в 19:44.
За это сообщение автора поблагодарили: ax_mct (9), sukhanchik (10), macklakov (10), Logger (3).
Старый 01.06.2017, 20:02   #85  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от mazzy Посмотреть сообщение
именно!
ключевое слово "сделать".
если нужно "сделать", то зачем нужен какой-то левый ключ?
давайте будем "сделать" сразу имя класса? и атрибутов писать не нужно.
Проанализируй ключ в твоем примере - он составной - модуль и Node - можно их заменить именами классов?

Цитата:
Снова приношу свои извинения за безумную реализацию от МС.
Нет, у меня не нужен класс запускач. Достаточно menuItem, который подцепляется к главному меню или к формам.
У тебя есть класс с методом main, который все это знает. Я думал ты его имеешь ввиду. Я не создавал новых классов кроме атрибута. Есть класс-создаватель (фабрика) он готовый и я его не менял.

Цитата:
Нет )))
На реальных проектах простейший случай без стратегии - скорее исключение.
На реальных проектах именно "стратегия" и зашита-размазана в конструкторах. Каждый конструктор отвечает за свою часть.
Тогда выбери любой другой пример. В принципе, ты прав, можно обойтись только классами, только надо добавить какой-то унифицированный способ связывать классы с существубщей инфраструктурой и тогда цепочка класов будет создавать нужный.

Цитата:
В фреймворке один стратегия должна знать обо всех классах иерархии.
Не понял.

Цитата:
ты снова прав для случая без параметров.
но как часто используется именно этот сценарий?
Я уже отвечал. Если нужны параметры конструктора, то используется следующий прием:

1. Во базовый класс добавляется метод init с нжными параметрами
2. Сразу после создания он вызывается.

Цитата:
выбери любой из них, который реализует несколько уровней иерархии.
Тебе нужна иерархия классов или иерархия ключей?
Если первое, то атрибуты никак не должны эту иерархию отражать, если второе, то то есть отдельная обертка для иерархических атрибутов, которая, правдя использована неколько раз там где надо делать классы ключами.

Цитата:
Покажи как это просто.

Ты говоришь "просто добавить атрибуты".
Ты говоришь "просто смотреть"
Сделай проектик. Покажи как это просто.
Ok чуть попозже. Только учти что у тебя добавление элемента к существующему механизму создания объектов. А у меня будет еще и немного кода на перевод на новый механизм (как если бы ты перевел все на if вместо case )

Цитата:
И в самом деле! Чего это я? Видать Котлинов всяких наелся...
Асинхронность это другой ортогональный аспект - нафига она тебе в создании экземпляра класса.

Цитата:
Я смотрю актуальную аксапту. 7.2.1785.0
Да-да. Я вижу это "что угодно". Строка с ; Это пипец и детский сад какой-то.
Это я не понял.

Цитата:
Кем и как? Бгггг!!
Так же как и сейчас - кто и как распределяет префиксы в именах классов, чтобы партнерские классы не конфликтовали с микрософтовскими при обновлении.

Цитата:
вспомнить, исходный вопрос ветки был: "Какая цель создания экземпляров классов через расширенные атрибуты? Чем не устраивает старый дедовский способ construct?"
- дает возможность разбить систему на независимые модули
- путем сведения общего пттерна "case" к частному "содание по ключу" позволяет автоматически сливать изменения в коде.

Цитата:
Ребяты, прошу вас, не надо примеров "я создал пример из трех классов, я добавил атрибуты". такие примеры ничего не показывают.
Зачем ты его просишь тогда?

Цитата:
Давайте рассматривать нормальный промышленный случай:
= которые добавляют/изменяют функционал этого семейства (одновременно или последовательно). в пределе это программисты разных партнеров, которые делают разные типовые решения. а некий программист заказчика ставит эти пересекающиеся типовые решения [из разных моделей]. (в целях упрощения, для данной ветки можно предположить, что модель одна, чтобы рассмотреть только механизм инстанцирования класса)
= как облегчить работу этих людей?
(Заметь что ты используешь разметку типа маркдауна внутри сообщения, но свою )

Как раз паттерн позволяет вынести реализации каких-то веще в модели. Например в настройках можно добавить baseenum с форматомданных, а вам класс который реализует вывод в него вынести в расширение в другой модели.

Цитата:
Как должны выглядеть эти ключи, чтобы разные люди могли добавлять классы-потомки и не мешать друг-другу?
Я видел два способа. 1) GUID 2) Сесть на какой-то уже готовый способ распределения имен, например в java привязываются к домену комании (com.microsoft.dynsmics.forOperations) который распределяется в интернете.

Я предпочитаю привязываться к именам классов и таблиц.

Цитата:
Как должны выглядеть эти ключи, чтобы в принципе была возможность рефакторинга? (да, я знаю что МС не рефакторит, но у партнеров и у заказчика то могут работать нормальные люди)
MS рефакторит. Несмотря на то, что при создании класса используется reflection это никак не мешает рефакторить, так как сами классы вполне себе поддерживают статические интерфейсы.

Цитата:
Зачем вообще нужны специальные ключи вместо имен классов?
Чтобы создавать классы на основе бейзэнамов, например. В принципе, можно было бы обойтись одними классами, но MorphX не поддерживает автоматизацию создания UI для классов. Именно поэтому твой case не по классам а по base enum и строчке - в menuItem нельзя записать три параметра все из которых были бы классами.

Еще можно использовать сами классы в качестве ключей - посмотри SysClassNameAttribute
За это сообщение автора поблагодарили: macklakov (10).
Старый 01.06.2017, 20:15   #86  
ax_mct is offline
ax_mct
Banned
 
2,548 / 1091 (0) ++++++++
Регистрация: 10.10.2005
Адрес: Westlands
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Не получится.
Передаем параметром в new ассоциативный массив, то же Map [имя переменной - key, ее значение - value]. Учим корень типа Object это парсировать.
Альтернативно передаем ключом внешнее имя переменной, mapping держим в ИмяКласса.xml.
Патентуем и подаем на Нобелевскую Премию.

Цитата:
Сообщение от mazzy Посмотреть сообщение
теперь новый проект на атрибутах.
Снимаю шляпу.
Но на лабутенах!!!
Старый 01.06.2017, 21:45   #87  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от belugin Посмотреть сообщение
Проанализируй ключ в твоем примере - он составной - модуль и Node - можно их заменить именами классов?
можно.
только в этом случае связь с инфраструктурой аксапты тоже вручную писать нужно будет.
поэтому я использовал menuItem.

Цитата:
Сообщение от belugin Посмотреть сообщение
У тебя есть класс с методом main, который все это знает. Я думал ты его имеешь ввиду. Я не создавал новых классов кроме атрибута. Есть класс-создаватель (фабрика) он готовый и я его не менял.
в проекте на конструкторах не было main, который ВСЕ ЗНАЕТ. было main, которые знали о себе (как обычно)
в проекте на конструкторах не было contruct, который ВСЕ ЗНАЕТ. было два конструктора. каждый знает только о своем уровне и принимает решение своего уровня.

в новом проекте на атрибутах действительно есть main, который должен знать обо всей иерархии. в проектике этого нет, потому что нет валидации входных данных. но в реальной жизни такая валидация обязательна.

Цитата:
Сообщение от belugin Посмотреть сообщение
Тогда выбери любой другой пример.
не, давай пока останемся на том же самом - расширить функционал автосопоставления.
по идее, в этом примере не хватает параметров. ну и фиг с ними.

Цитата:
Сообщение от belugin Посмотреть сообщение
Я уже отвечал. Если нужны параметры конструктора, то используется следующий прием:
Макс, ты снова рассказываешь "как это работает".
Я верю. Теперь я даже это видел своими глазами. "Прием" есть конечно.

Давай лучше поговорим о трудоемкости и об ответстенности за правильность результата.
Как бы ты оценил трудоемкость и удобность по сравнению со старым методом?
Мое мнение: Через жопу по сравнению со старым конструкторским методом.

Цитата:
Сообщение от belugin Посмотреть сообщение
Тебе нужна иерархия классов или иерархия ключей?
...атрибуты никак не должны эту иерархию отражать
Вооот!!!
И мы подошли к трудоемкости и удобствам.

Раньше программист должен был знать только иерархию классов.
Теперь иерархия классов может (и должна) не совпадать с иерархией атрибутов.
Теперь программисту надо знать три вещи - иерархию классов, иерархию атрибутов и маппинг между ними. Во всех трех вещах могут быть ошибки. А поскольку в новом методе никакого контроля на этапе компиляции, то в новом методе ошибки будут неизбежно. Следовательно, потребуется большее время на изучение, написание, отладку и тестирования.


Цитата:
Сообщение от belugin Посмотреть сообщение
Если первое, ... если второе, то ... правдя использована неколько раз там где надо делать классы ключами.
Именно!
Я посмотрел в существующий функционал насколько хватило терпения.
Пипец!!!

Цитата:
Сообщение от belugin Посмотреть сообщение
Ok чуть попозже. Только учти что у тебя добавление элемента к существующему механизму создания объектов. А у меня будет еще и немного кода на перевод на новый механизм (как если бы ты перевел все на if вместо case )
Если обратишь внимание, то во втором проекте у меня классы переведены на новый механизм. Во втором проекте нет конструкторов вообще.

Про добавление - я помню документацию и помню твои слова, где было только "добавление классов".
А вообще говоря, фреймворк должен успешно решать еще и задачи рефакторинга, изменения существующего функционала.
Я писал об этом выше.

Но фиг с ним. Давай пока останемся в рамках задачи "добавление класса в иерархию"

Цитата:
Сообщение от belugin Посмотреть сообщение
Асинхронность это другой ортогональный аспект - нафига она тебе в создании экземпляра класса.
Да, ортогональный
Да, никакой асинхронности.
Да, я совершенно зря загорелся надеждой...

Цитата:
Сообщение от belugin Посмотреть сообщение
Так же как и сейчас - кто и как распределяет префиксы в именах классов, чтобы партнерские классы не конфликтовали с микрософтовскими при обновлении.
"Также как и сейчас" - это ты очень хорошо сказал.
Если "также как и сейчас", то нафига огород городить?
А да, вспомнил, МС закрывает код базовых классов...

Цитата:
Сообщение от belugin Посмотреть сообщение
- дает возможность разбить систему на независимые модули
- путем сведения общего пттерна "case" к частному "содание по ключу" позволяет автоматически сливать изменения в коде.
да-да. это понятно.
но я уже говорил, что это не единственный способ. и далеко не оптимальный.

Цитата:
Сообщение от belugin Посмотреть сообщение
Зачем ты его просишь тогда?
и в самом деле!

Цитата:
Сообщение от belugin Посмотреть сообщение
(Заметь что ты используешь разметку типа маркдауна внутри сообщения, но свою )
Заметь, что в эту разметку никто не будет встраивать свои сообщения. На форуме при цитировании делается копия, старый текст и добавляется текст. И здесь нет компиляции )))

Цитата:
Сообщение от belugin Посмотреть сообщение
Как раз паттерн позволяет вынести реализации каких-то веще в модели. Например в настройках можно добавить baseenum с форматомданных, а вам класс который реализует вывод в него вынести в расширение в другой модели.
Макс... Я понимаю что ты хочешь сказать. Но просто сделай проектик (чуть более сложный чем одноувроенвое семейство из трех классов) И покажи в нем что хочешь сказать.

Цитата:
Сообщение от belugin Посмотреть сообщение
MS рефакторит. Несмотря на то, что при создании класса используется reflection это никак не мешает рефакторить
...майкрософту. пока билд не выпущен ))))
остальные не могут.
а тут еще и доступ к изменению исходного кода закроют.

Цитата:
Сообщение от belugin Посмотреть сообщение
Чтобы создавать классы на основе бейзэнамов, например.
я понимаю, что ты хочешь сказать. но так делают только внутри МС.

Цитата:
Сообщение от belugin Посмотреть сообщение
Именно поэтому твой case не по классам а по base enum и строчке - в menuItem нельзя записать три параметра все из которых были бы классами.
Вот ведь блин, выбрал я пример...
еще раз извиняюсь за дебильную реализацию семейства классов от МС - наши люди в булошную на такси не ездют нормальные люди так не делают.
но фреймворк должен работать и с такими примерами тоже.

Цитата:
Сообщение от belugin Посмотреть сообщение
Еще можно использовать сами классы в качестве ключей - посмотри SysClassNameAttribute
Да-да. У меня это был второй или третий вариант. В этом случае связь с классами автоматом, но зато связь с menuItem нужно делать руками.

Я старался сделать минимальный код при помощи штатных средств.
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 01.06.2017 в 21:52.
Старый 01.06.2017, 22:21   #88  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от mazzy Посмотреть сообщение
можно.
только в этом случае связь с инфраструктурой аксапты тоже вручную писать нужно будет.
поэтому я использовал menuItem.
Заметь, что в исходном проекте использующем case делается специальное текстовое значение, которое повторяется в нескольких местах.

Цитата:
в проекте на конструкторах не было main, который ВСЕ ЗНАЕТ. было main, которые знали о себе (как обычно)
в проекте на конструкторах не было contruct, который ВСЕ ЗНАЕТ. было два конструктора. каждый знает только о своем уровне и принимает решение своего уровня.
Это ограничение, да, для каких-то сложных свопобов создания это не очень подходит. Но приведенный пример к ним не относится: родительский construct знает о существовании ключей, которые передает дальше.

Цитата:
в новом проекте на атрибутах действительно есть main, который должен знать обо всей иерархии. в проектике этого нет, потому что нет валидации входных данных. но в реальной жизни такая валидация обязательна.
В чем проблема с валидацией? Если ее надо делать до определения потомка, то вставить в вызывающий класс, если после, то в базовый.

Цитата:
Давай лучше поговорим о трудоемкости и об ответстенности за правильность результата.
Как бы ты оценил трудоемкость и удобность по сравнению со старым методом?
Мое мнение: Через жопу по сравнению со старым конструкторским методом.
Трудоемкость какого сценария? Добавление нового элемента - чуть меньше. Создание самой точки расширения - чуть больше или такая же.
Апгрейда при условии отсутствия breaking changes меньше.
Поиска зависимостей - примерно такая же.

Цитата:
Раньше программист должен был знать только иерархию классов.
Теперь иерархия классов может (и должна) не совпадать с иерархией атрибутов.
Тут никакой иерархии атрибутов нет, атрибут ровно один.

Цитата:
Теперь программисту надо знать три вещи - иерархию классов, иерархию атрибутов и маппинг между ними.
Никакой иерархии атрибутов нет, меппинг не надо знать он как читается в коде как и раньше, только другим способом.

Цитата:
Во всех трех вещах могут быть ошибки. А поскольку в новом методе никакого контроля на этапе компиляции, то в новом методе ошибки будут неизбежно.
В новом - меньше.

Цитата:
Да, ортогональный
Да, никакой асинхронности.
Да, я совершенно зря загорелся надеждой...
При чем тут вообще асинхронность и создание экземпляров классов.

Цитата:
"Также как и сейчас" - это ты очень хорошо сказал.
Если "также как и сейчас", то нафига огород городить?
Чтобы в других аспектах было не так же как и сейчас. Не все сразу.

Цитата:
Макс... Я понимаю что ты хочешь сказать. Но просто сделай проектик (чуть более сложный чем одноувроенвое семейство из трех классов) И покажи в нем что хочешь сказать.
Сконвертировал пример c case на жкстеншены. Не тестировал - мне кажется ты разобрался в концепции.
Вложения
Тип файла: axpp max.axpp (13.5 Кб, 66 просмотров)
За это сообщение автора поблагодарили: mazzy (5).
Старый 01.06.2017, 22:32   #89  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
> 1. нужно указывать базовый класс
> 2. нужно делать cast. для этого нужно знать к какому базовому классу кастить.

Тут извиняйте, если бы были дженерики, можно было бы сделать

X++:
var x = SysExtensionAppClassFactory::getClassFromSysAttribute<MyBaseClass>(attribute)
И не дублировать тип.

Кстати в данном случае надо использовать не is - он вернет null если вдруг будет не ожидаемый тип а просто обявить явно тип без var - это будет все равно что строгий каст в C# (тип в скобочках).

> в семействе может быть несколько базовых с разной логикой. см FormLetter.

Дык все равно ты тут одижаешь какой-то один тип - класс или интерфейс, если разные, то надо либо делать разные плагины либо дальше кастить - без этого логически никак.
Старый 02.06.2017, 07:51   #90  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Спасибо за проект. Посмотрю.

Цитата:
Сообщение от belugin Посмотреть сообщение
Кстати в данном случае надо использовать не is
ага. я тоже так подумал. но этот код скопирован из существующего в аксапте.

я стремился сделать штатными средствами и максимально похожим на штатную функциональность. )
__________________
полезное на axForum, github, vk, coub.
Старый 02.06.2017, 08:07   #91  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от mazzy Посмотреть сообщение
ага. я тоже так подумал. но этот код скопирован из существующего в аксапте.
is можно использовать, но только в том случае, когда в значении может быть другой класс и это валидный кейз. После чего значение перед использованием надо обязательно проверить на null. К сожалению, это частая ошибка использовать одно вместо другого. К сожалению, в X++ нету явного строгого приведения.
Старый 03.06.2017, 07:58   #92  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от mazzy Посмотреть сообщение
это не единственный способ. и далеко не оптимальный.
как можно было бы реализовать,
если бы разработчикам поставили правильную задачу:
"создать фреймворк для добавления и изменения функционала, который будет доступен пользователям"

вместо нелепой задачи
"создать фреймворк для добавления классов"

============================
идея очень простая:
  • не нужно никаких дополнительных классов-запускачей.
  • [стандартный функционал] каждый класс запускается при помощи menuItem. в menuItem хранится объект, который должен быть запущен + метка + права + доп.строка параметров
  • [стандартный функционал] menuItem запускает статический метод main
  • [стандартный функционал] В main явно вызывается базовый класс с Args и добавленными в фреймворк стратегиями запуска
  • [стандартный функционал] все контролируется штатными правами и штатными menuItem'ами.
  • [стандартный функционал] окружение и инструменты (например, перекрестные ссылки) остаются в штатных режимах
  • [стандартный функционал] класс можно вызывать из кода как при помощи menuFunction, так и вручную сформировав Args и запустив main.
  • при правильных args, из кода можно запускать как main базового класса, так и main нужного класса
  • construct базового класса вызывает фреймворк.
  • каждый класс знает о себе, о своем базовом классе и о своей стратегии. ни одному классу, ни одному методу не нужно знаний обо всей иерархии.
  • базовый класс можно сделать readOnly
  • при желании, логику инстанцирования можно задавать при помощи параметра, а можно оставлять дефолтную
  • при желании, логику запуска run можно задавать при помощи прараметра, а можно оставлять дефолтную

X++:
abstract class BaseClass_ReadOnly extends RunBaseBatch
{
    protected static baseClass_ReadOnly construct(Args _args /*, SysExtensionInstantiationStrategy strategy = null*/)
    {
        var attr = new FormMenuItemFactoryAttribute(_args.menuItemType(), _args.menuItemName());
        var obj = SysExtensionAppClassFactory::getClassFromSysAttribute(classStr(baseClass_ReadOnly), attr); 

        //TODO add initialization strategy

        return obj;
    }

    public static void main(Args _args /*, SysExtensionInstantiationStrategy initStrategy = null */ )
    {
        baseClass_ReadOnly obj = BaseClass_ReadOnly::construct(_args /*, initStrategy */);

        //TODO run strategy. Default is:
        if( obj && obj.Prompt() )
        {
            obj.run();
        }        
    }

}
вообще говоря, при правильно сформированных args, атрибут избыточен.
но для текущей версии фреймворка атрибут нужен.
X++:
[FormMenuItemFactoryAttribute(MenuItemType::Action, menuItemActionStr(myMenuItem))]
class MyClass extends BaseClass_ReadOnly
{
    public void run()
    {
        //TODO something useful
    }

    public static void main(Args _args)
    {
        MyClass obj = BaseClass_ReadOnly::constuct(_args);

        //TODO run strategy. Default is:
        if( obj && obj.Prompt() )
        {
            obj.run();
        }        
    }

}
menuItem указывает на нормальный объект
Код:
<?xml version="1.0" encoding="utf-8"?>
<AxMenuItemAction xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="Microsoft.Dynamics.AX.Metadata.V1">
	<Name>myMenuItem</Name>
	<Object>myClass</Object>
	<ObjectType>Class</ObjectType>
</AxMenuItemAction>

=====================
кто-нибудь хочет проанализировать и рассказать про еще один фреймворк SysPlugin, который должен решать аналогичные задачи?
лучше в отдельной ветке.
__________________
полезное на axForum, github, vk, coub.
Старый 03.06.2017, 08:55   #93  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Спасибо добрым людям, которые подсказывают, что:
  • уже есть ClassFactory.createClass() для создания экземпляра класса c проверкой свойств в AOT
  • уже есть MenuFunction.create() для создания интерфейсных объектов при помощи menuItem
  • уже есть MenuFunction.run() для запуска любого объекта при помощи menuItem с проверкой security.

Новый фреймворк Скрипач не нужен, Дядя Вова. (С)

Если уж так хочется сделать фреймворк, то скомбинировали бы два существующих класса.
Если уж так хочется заменить makeObject на .net инстанцирование, которое "в 4 раза быстрее", то изменили бы код в существующих классах.

А всего то разница в постановке задачи.
МС-разработчикам сказали сделать добавление классов, но не сказали как это будет использоваться. Они и сделали ТОЛЬКО добавление классов.
Эх...
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 03.06.2017 в 09:18.
Старый 03.06.2017, 21:11   #94  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1296 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Цитата:
Сообщение от ta_and Посмотреть сообщение
Приведите хотя бы один довод, почему в конструктор не должны передаваться параметры?
Извините, что есть задержка с ответом - сменил место работы и после 15 лет работы в производстве теперь много времени уходит на то, чтобы понять что же такое "ритейл".
Для начала, чтобы не тратить время, определимся что такое конструктор. На мой взгляд, конструктор это то, что создает класс. В Аксе это метод new. Принято создавать статический метод construct, но, несмотря на название это все-таки не конструктор в общем понимании, а метод фабрики.
Пример проблемы параметров в new очень простой (речь про DAX2009, то есть пока про атрибуты даже не вспоминаем).
Создаем наследника RunBaseBatch в котором в new указываем параметры. Если запускаем этот класс через назначенный mtnuitem, то проблем нет. А теперь, представляем ситуацию, когда наш класс администратор хочет включить в пакетное задание в рамках журнала.
Он запускает "Основное \ Запросы \ Пакетное задание. Создает новое задание, переходит в "Просмотр задач", создает новую строку и пытается выбрать класс обработки. И получает ошибку, причем непонятную - я встречал и "тип операнда не соответствует оператору" и "типы несовместимы" и другие и без всякого указания на класс, вызвавший проблему.
На самом деле, даже не нужно создавать свой класс, MS, о нас позаботился и создал два такие класса. Если у Вас есть DAX2009 с Российской локализацией, включающей зарплату, то механизм создания журнала пакетного задания уже сломан из-за использования параметров в new. Пример тут: Создание пакетного задания DAX 2009

Последний раз редактировалось Raven Melancholic; 03.06.2017 в 21:17.
Старый 03.06.2017, 21:26   #95  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1296 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Теперь вернемся к методу construct.
Я то же не понимаю, почему для какого-то метода фабрики класса есть ограничения в BP. То есть, если я хочу фабрику назвать construct, то должен следовать BP и делать его без параметров, а если хочу назвать make, то могу делать что угодно (название create не рассматриваем, оно без предупреждения в каких-либо описаниях используется для распаковки).
Опять же ответ в том, как стандартное приложение ожидает в некоторых местах наличие и следование определенным правилам методов. Сам лично не сталкивался в реальной работе с проблемой (в отличие от метода new с параметрами) construct с параметрами, но видел ,что есть места, в которых в стандартном приложении есть вызова статического метода construct ожидающие, что он без параметров.
Старый 03.06.2017, 21:38   #96  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1296 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Цитата:
Я говорю именно о месте, где производится инициализация объекта нового класса.
Там тоже, даже при использовании не атрибутов, а switch совсем не обязательно, что будет создан класс, который мы указали.
Например, мы сказали в своем case, что создать Наследник::make(нечто). Когда писали вызов создания этот наследник был именно "Наследник", но впоследствии разработчик "Наследника" решил что он слишком много на себя берет и разбил его на несколько классов со своей структурой наследования, а в make написал что-то, что в зависимости от состава "нечто" создает нужного наследника. То есть, в своем классе мы не можем предполагать, что же именно будет создано. Мы можем только надеяться, что поведение будет нужным нам.
Кстати, не вижу разницы, будет ли фабрика при создании классов опираться на switch-case или аттрибуты.
Старый 03.06.2017, 21:58   #97  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1296 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Понимаю, что mazzy ждет от поведения системы (то же что и другие люди, знакомые в Аксой, в том числе и я): привычные подходы, которые используются кучу лет, простые способы внесения изменений, ловлю любых зависимостей перекрестными ссылками и т.п. Оставим пока слухи о том, что, не исключено, что могут вообще быть закрыты некоторые способы изменений.
Я не очень понимаю, почему mazzy считает, что изменение иерархии путем включения какого-то класса не в качестве последнего листа, а в середину иерархии отличается при использовании фабрики, основанной на атрибутах и фабрики, основанной на switsh-case? Один фиг в обоих случаях придется искать все объявления переменных класса, который был раньше непосредственным наследником, а теперь переместился по иерархии выше, чем был ранее.
Старый 03.06.2017, 22:06   #98  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от mazzy Посмотреть сообщение
  • не нужно никаких дополнительных классов-запускачей.
  • [стандартный функционал] каждый класс запускается при помощи menuItem. в menuItem хранится объект, который должен быть запущен + метка + права + доп.строка параметров
Никаких запускачей и нет. Есть не запускач, а создавач. Люди которые читали книжку GoF его называют фабрикой, просто потому, что не догадались до имени "создавач" .

Классы бывают не только вызываемые из непосредственно из UI, не только с методами main но и всякие другие. Использование контроля прав доступа нужно далеко не везде. (Я кстати не видел нигде ключевой атрибут по mеnuitem - тут ты ломишься в открытую дверь - если класс именно вызывается - то есть потомок runbase, и по меню айтем можно его однозначно определить, то он связывается с ним непосредственно).

Последний раз редактировалось belugin; 03.06.2017 в 22:18.
Старый 04.06.2017, 22:26   #99  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Raven Melancholic Посмотреть сообщение
теперь много времени уходит на то, чтобы понять что же такое "ритейл".
велкам.

Цитата:
Сообщение от Raven Melancholic Посмотреть сообщение
Для начала, чтобы не тратить время, определимся что такое конструктор. На мой взгляд, конструктор это то, что создает класс. В Аксе это метод new. Принято создавать статический метод construct, но, несмотря на название это все-таки не конструктор в общем понимании, а метод фабрики.
да. согласен.

Цитата:
Сообщение от belugin Посмотреть сообщение
Никаких запускачей и нет. Есть не запускач, а создавач. Люди которые читали книжку GoF его называют фабрикой, просто потому, что не догадались до имени "создавач" .
да. фабрика. согласен, хороший стандартный термин. и уводит от путаницы с constructor.


Цитата:
Сообщение от belugin Посмотреть сообщение
А теперь, представляем ситуацию, когда наш класс администратор хочет включить в пакетное задание в рамках журнала.
Журнал - это сильно obsolete инструмент.
насколько я помню, это было еще до того, как научились сохранять параметры диалога для пакетных заданий.
сейчас скорее будет запущено что-то через главное меню или через меню в какой-то форуме.


Цитата:
Сообщение от Raven Melancholic Посмотреть сообщение
Понимаю, что mazzy ждет от поведения системы (то же что и другие люди, знакомые в Аксой, в том числе и я): привычные подходы, которые используются кучу лет, простые способы внесения изменений, ловлю любых зависимостей перекрестными ссылками и т.п.
не совсем так. пусть они будут непривычными.
но пусть будут такими, что покрывают множество сценариев использования. пусть они будут универсальными.

Цитата:
Сообщение от Raven Melancholic Посмотреть сообщение
Я не очень понимаю, почему mazzy считает, что изменение иерархии путем включения какого-то класса не в качестве последнего листа, а в середину иерархии отличается при использовании фабрики, основанной на атрибутах и фабрики, основанной на switsh-case?
вы тоже говорите о добавлении класса.
я говорю о добавлении функционала, который потом будет предоставлен пользователям.

чтобы предоставить пользователям добавленный класс, нужен будет menuItem.


Цитата:
Сообщение от belugin Посмотреть сообщение
Классы бывают не только вызываемые из непосредственно из UI, не только с методами main но и всякие другие. Использование контроля прав доступа нужно далеко не везде. (Я кстати не видел нигде ключевой атрибут по mеnuitem - тут ты ломишься в открытую дверь - если класс именно вызывается - то есть потомок runbase, и по меню айтем можно его однозначно определить, то он связывается с ним непосредственно).
может. бывают. можно однозначно определить.
не нужен UI - просто создай menuItem и ничего с ним не делай. понадобиться - просто продолжай использовать menuItem.
в отличие от атрибута.

вы снова говорите как это работает.
это работает.

я говорю о трудоемкости и стоимости работ на разобраться, добавить функционал, дать пользователю, поддерживать в дальнейшем.

технология на атрибутах требует двойных-тройных трудозатрат. я только об этом.
и да: большинство преимуществ атрибутов можно проявить только для решения внутренних МСовских задач и только в окружении МС, где атрибуты уже повсеместно используются. Там таки да - шикардос и позднее связывание рулит. остальным только усложнит жизнь.
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 04.06.2017 в 22:41.
Старый 04.06.2017, 23:06   #100  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от mazzy Посмотреть сообщение
технология на атрибутах требует двойных-тройных трудозатрат.
чтобы не быть голословным.
по существующей технологии - для того, чтобы помечать атрибутом, нужно создать класс атрибута и прописать как параметры будут преобразованы в ключ.

всего сейчас 83 потомка от SysExtensionAttribute.
3 из них универсальные - enum, menuItem, dataset.
остальные - как правило просто специализированные классы для enum'ов. (почему не универсальный FormEnumSymbolFactoryAttribute? а ХЗ. универсальный класс сейчас используется только в 8 местах)

так вот, получается, чтобы работать по текущим рекомендациям с атрибутами, нужно:
= создать сам класс и встроить его в иерархию
= разобраться с классом атрибутов и встроить туда (или создать класс атрибутов)
= разобраться с фабрикой и встроить туда
= добавить menuItem, если нужно дать функционал пользователю, разобраться как menuItem должен запустить нужный класс

плюс работа, которой никогда нет в МС, но частенько бывает на проекте - решить что делать с функционалом, который добавлен разными партенрами. раньше пересечения нужно было искать только в construct. теперь пересечения нужно искать по разнообразным семействам - классы, атрибуты, стратегии инстанцирования, menuItem.
Миниатюры
Нажмите на изображение для увеличения
Название: 1.PNG
Просмотров: 358
Размер:	61.2 Кб
ID:	11471   Нажмите на изображение для увеличения
Название: 2.PNG
Просмотров: 252
Размер:	37.4 Кб
ID:	11472  

__________________
полезное на axForum, github, vk, coub.
Теги
sysextension framework, sysoperation framework, как правильно, полезное

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
stephenmann: Technical History of Dynamics AX - From Axapta 3.0 to AX2012 Blog bot DAX Blogs 5 03.03.2017 10:22
dynamicsax-fico: Invoice search AX2012 vs. AX7 (Part 2) Blog bot DAX Blogs 0 01.04.2016 10:11
DAX2009 аналог friend классов. Как сделать? Raven Melancholic DAX: Программирование 9 07.11.2015 23:50
emeadaxsupport: Inventory closing differences between AX4.0 and AX2012 using weighted average costing method Blog bot DAX Blogs 0 27.12.2012 19:11
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 08:22.