Коришћење СисЕктенсион Фрамеворк-а да бисте сазнали коју подкласу треба инстанцирати у Динамицс АКС 2012
Објављено: 16. фебруар 2025. 00:29:31 UTC
Последње ажурирано: 12. јануар 2026. 08:43:48 UTC
Овај чланак описује како се користи мало познати SysExtension оквир у Dynamics AX 2012 и Dynamics 365 for Operations за креирање подкласа на основу декорација атрибута, што омогућава лако прошириви дизајн хијерархије класа обраде.
Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012
Информације у овом посту су засноване на Dynamics AX 2012 R3. Могу, али и не морају бити важеће за друге верзије. (Ажурирање: Могу да потврдим да информације у овом чланку важе и за Dynamics 365 for Operations)
Приликом имплементације класа за обраду у Dynamics AX-у, често се суочавате са креирањем хијерархије класа у којој свака подкласа одговара вредности набрајања или има неку другу везу података. Класичан дизајн је да се затим у надкласи појави метода конструкције, која има прекидач који одређује коју класу треба инстанцирати на основу улаза.
Ово у принципу добро функционише, али ако имате много различитих могућих улаза (много елемената у набрајању или је можда улаз комбинација неколико различитих вредности), одржавање може постати заморно и склоно грешкама, а дизајн увек има ману што ћете морати да модификујете поменути метод конструкције ако икада додате нову подкласу или направите промене у томе која подкласа треба да се користи на основу ког улаза.
Срећом, постоји много елегантнији, али нажалост и много мање познат начин да се то уради, наиме коришћењем SysExtension оквира.
Овај фрејмворк користи атрибуте које можете користити за декорисање ваших подкласа како би систем могао да утврди која подкласа треба да се користи за руковање чиме. И даље ће вам бити потребна метода конструкције, али ако се уради исправно, никада је нећете морати модификовати приликом додавања нових подкласа.
Погледајмо замишљени пример и рецимо да ћете имплементирати хијерархију која врши неку врсту обраде на основу табеле InventTrans. Која обрада ће се извршити зависи од StatusReceipt и StatusIssue записа, као и од тога да ли су записи повезани са SalesLine, PurchLine или ниједним. Већ сада видите много различитих комбинација.
Рецимо да знате да за сада треба да обрадите само неколико комбинација, али такође знате да ће се од вас тражити да будете у стању да обрадите све више и више комбинација током времена.
Хајде да то буде релативно једноставно и да кажемо да за сада треба да обрађујете само записе везане за SalesLine са StatusIssue вредношћу ReservPhysical или ReservOrdered, све остале комбинације се за сада могу игнорисати, али пошто знате да ћете морати да их обрађујете касније, желећете да дизајнирате свој код на начин који га чини лако проширивим.
Ваша хијерархија за сада може изгледати отприлике овако:
- МојПроцесорМојПроцесор_ПродајаМојПроцесор_Резерва_ПродајеНарученоМоја_Процесор_Резерва_ПродајеФизичка
Сада бисте лако могли да имплементирате методу у надкласи која инстанцира подкласу на основу ModuleInventPurchSales и StatusIssue набрајања. Али ћете тада морати да мењате надкласу сваки пут када додате подкласу, а то није заправо идеја наслеђивања у објектно оријентисаном програмирању. На крају крајева, не морате да мењате RunBaseBatch или SysOperationServiceBase сваки пут када додате нови пакетни задатак.
Уместо тога, можете користити SysExtension фрејмворк. То ће захтевати да додате још једну класу, која треба да прошири SysAttribute. Ова класа ће се користити као атрибут којим можете украсити своје класе за обраду.
Ова класа је веома слична начину на који бисте направили класу уговора о подацима за имплементацију SysOperation, по томе што ће имати неке чланове података и parm методе за добијање и подешавање тих вредности.
У нашем случају, декларација класе може изгледати отприлике овако:
{
ModuleInventPurchSales module;
StatusIssue statusIssue;
StatusReceipt statusReceipt
}
Потребно је да направите метод `new()` за инстанцирање свих чланова података. Ако желите, можете дати неким или свима подразумеване вредности, али ја то нисам урадио.
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
;
super();
module = _module;
statusIssue = _statusIssue;
statusReceipt = _statusReceipt;
}
Такође би требало да имплементирате парм метод за сваки члан података, али сам их овде изоставио јер сам сигуран да знате како се то ради - у супротном, хајде да то сматрамо вежбом ;-)
Сада можете користити своју класу атрибута за декорисање сваке од ваших класа обраде. На пример, декларације класа могу изгледати овако:
StatusIssue::None,
StatusReceipt::None)]
class MyProcessor_Sales extends MyProcessor
{
}
[MyProcessorSystemAttribute(ModuleInventPurchSales::Sales,
StatusIssue::ReservOrdered,
StatusReceipt::None)]
class MyProcessor_Sales_ReservOrdered extends MyProcessor_Sales
{
}
[MyProcessorSystemAttribute(ModuleInventPurchSales::Sales,
StatusIssue::ReservPhysical,
StatusReceipt::None)]
class MyProcessor_Sales_ReservPhysical extends MyProcessor_Sales
{
}
Наравно, можете именовати своје класе како год желите, важно је да украсите своје класе атрибутима који одговарају врсти обраде коју обављају. (Али имајте на уму да постоје конвенције именовања за хијерархије класа у Dynamics AX-у и увек је добра идеја да их се придржавате, ако је могуће).
Сада када сте украсили своје класе да бисте идентификовали коју врсту обраде свака од њих обавља, можете искористити SysExtension оквир да бисте инстанцирали објекте подкласа по потреби.
У вашој суперкласи (MyProcessor), можете додати метод конструкције попут овог:
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
MyProcessor ret;
MyProcessorSystemAttribute attribute;
;
attribute = new MyProcessorSystemAttribute( _module,
_statusIssue,
_statusReceipt);
ret = SysExtensionAppClassFactory::getClassFromSysAttribute(classStr(MyProcessor), attribute);
if (!ret)
{
// no class found
// here you could throw an error, instantiate a default
// processor instead, or just do nothing, up to you
}
return ret;
}
Заиста занимљив део - и заиста циљ (опростите на каламбуру) целог овог поста - је метода getClassFromSysAttribute() у класи SysExtensionAppClassFactory. Ова метода прихвата име надкласе хијерархије (и ова надкласа не мора бити на врху хијерархије; то једноставно значи да ће само класе које проширују ову класу бити подобне) и објекат атрибута.
Затим враћа објекат класе која проширује наведену суперкласу и украшена је одговарајућим атрибутом.
Очигледно је да можете додати онолико додатних валидација или логике методи construct колико желите, али важна ствар је да, када се једном имплементира, никада више не би требало да морате да мењате ову методу. Можете додати подкласе хијерархији и све док се побринете да их правилно декоришете, метод construct ће их пронаћи чак и ако нису постојале када је написана.
Шта је са перформансама? Искрено, нисам покушао да га упоредим са перформансама, али имам осећај да ово вероватно ради лошије од класичног дизајна са switch наредбама. Међутим, с обзиром на то да је убедљиво највише проблема са перформансама у Dynamics AX-у узроковано приступом бази података, не бих се превише бринуо око тога.
Наравно, ако имплементирате нешто што ће захтевати брзо креирање хиљада објеката, можда ћете желети даље да истражите, али у класичним случајевима где само правите инстанцију једног објекта да би се извршила дуготрајна обрада, сумњам да ће то бити важно. Такође, узимајући у обзир мој савет за решавање проблема (следећи пасус), чини се да се SysExtension фрејмворк ослања на кеширање, тако да у покренутом систему сумњам да има значајан ударац по перформансе.
Решавање проблема: Ако метода construct не пронађе ваше подкласе иако сте сигурни да су правилно декорисане, могуће је да је проблем у кеширању. Покушајте да обришете кеш и на клијенту и на серверу. Не би требало да буде потребно поново покренути AOS, али то може бити последња опција.
Даље читање
Ако сте уживали у овом посту, можда ће вам се свидети и ови предлози:
- Избришите правно лице (налози предузећа) у Динамицс АКС 2012
- Како прећи преко елемената енума из Кс++ кода у Динамицс АКС 2012
- Форматирање низа помоћу макроа и стрФмт-а у Динамицс АКС 2012
