SysExtension Frameworki kasutamine Dynamics AX-i 2012 alamklassi leidmiseks
Avaldatud: 16. veebruar 2025, kell 00:25:39 UTC
Selles artiklis kirjeldatakse, kuidas kasutada Dynamics AX-i 2012 ja Dynamics 365 for Operations vähetuntud SysExtensioni raamistikku, et luua atribuutide dekoratsioonidel põhinevaid alamklasse, võimaldades töötlemisklassi hierarhia hõlpsasti laiendatavat kujundust.
Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012
Selles postituses olev teave põhineb Dynamics AX-i 2012 R3-l. See võib teiste versioonide jaoks kehtida, kuid ei pruugi kehtida. (Värskendus: võin kinnitada, et selles artiklis olev teave kehtib ka Dynamics 365 for Operationsi jaoks)
Töötlemisklasside rakendamisel Dynamics AX-is peate sageli looma klassihierarhia, milles iga alamklass vastab loendi väärtusele või millel on mõni muu andmeside. Klassikaline disain on siis superklassis konstrueerimismeetod, millel on lüliti, mis määrab sisendi põhjal, milline klass instantseerida.
See toimib põhimõtteliselt hästi, kuid kui teil on palju erinevaid võimalikke sisendeid (palju elemente loendis või võib-olla on sisend mitme erineva väärtuse kombinatsioon), võib selle hooldamine muutuda tüütuks ja veaohtlikuks ning disainil on alati see miinus, et kui lisate uue alamklassi või teete muudatusi, millist alamklassi tuleks millise sisendi põhjal kasutada.
Õnneks on selleks palju elegantsem, kuid kahjuks ka vähem tuntud viis, nimelt SysExtensioni raamistiku kasutamine.
See raamistik kasutab ära atribuute, mida saate oma alamklasside kaunistamiseks kasutada, et süsteem saaks aru saada, millist alamklassi mille haldamiseks kasutada. Teil on endiselt vaja konstrueerimismeetodit, kuid kui see on õigesti tehtud, ei pea te seda uute alamklasside lisamisel kunagi muutma.
Vaatame väljamõeldud näidet ja ütleme, et kavatsete rakendada hierarhiat, mis töötleb InventTransi tabeli alusel. See, millist töötlemist teha, sõltub kirjete StatusReceiptist ja StatusIssuest, samuti sellest, kas kirjed on seotud SalesLine'i, PurchLine'iga või mitte kummagiga. Juba praegu vaatate palju erinevaid kombinatsioone.
Oletame siis, et teate, et praegu on teil vaja ainult käputäis kombinatsioone, kuid teate ka seda, et teil palutakse aja jooksul järjest rohkemate kombinatsioonidega hakkama saada.
Jätame selle suhteliselt lihtsaks ja ütleme, et praegu peate käsitlema ainult SalesLine'iga seotud kirjeid, mille StatusIssue on ReservPhysical või ReservOrdered, kõiki muid kombinatsioone võib praegu ignoreerida, kuid kuna teate, et peate nendega hiljem hakkama saama, peaksite oma koodi kujundama nii, et see oleks hõlpsasti laiendatav.
Teie hierarhia võib praegu välja näha umbes selline:
- MyProcessor
- MyProcessor_Sales
- MyProcessor_Sales_ReservOrdered
- MyProcessor_Sales_ReservPhysical
- MyProcessor_Sales
Nüüd saate superklassis hõlpsasti rakendada meetodi, mis loob alamklassi, mis põhineb ModuleInventPurchSales ja StatusIssue loendil. Kuid siis peate superklassi muutma iga kord, kui lisate alamklassi, ja see ei ole tegelikult objektorienteeritud programmeerimise pärimise idee. Lõppude lõpuks ei pea te RunBaseBatch'i ega SysOperationServiceBase'i iga kord uue pakktöö lisamisel muutma.
Selle asemel saate kasutada SysExtensioni raamistikku. Selleks peate lisama teise klassi, mis peab SysAttribute'i laiendama. Seda klassi kasutatakse atribuudina, millega saate oma töötlemisklasse kaunistada.
See klass on väga sarnane sellega, kuidas teete SysOperationi juurutuse jaoks andmelepingu klassi, kuna sellel on mõned andmeliikmed ja parm-meetodid nende väärtuste hankimiseks ja seadistamiseks.
Meie puhul võib klassideklaratsioon välja näha umbes selline:
{
ModuleInventPurchSales module;
StatusIssue statusIssue;
StatusReceipt statusReceipt
}
Kõigi andmeliikmete instantseerimiseks peate looma uue () meetodi. Soovi korral võite anda mõned või kõik vaikeväärtused, kuid ma pole seda teinud.
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
;
super();
module = _module;
statusIssue = _statusIssue;
statusReceipt = _statusReceipt;
}
Ja iga andmeliikme jaoks peaksite rakendama ka parm-meetodi, kuid ma olen need siin välja jätnud, kuna olen kindel, et teate, kuidas seda teha - muidu käsitleme seda harjutusena ;-)
Nüüd saate kasutada oma atribuutide klassi iga töötlemisklassi kaunistamiseks. Näiteks võivad klassideklaratsioonid välja näha järgmised:
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
{
}
Muidugi võite oma klasse nimetada nii, nagu soovite, oluline osa on siin see, et kaunistate oma klasse atribuutidega, mis vastavad nende töötlemisele. (Kuid pidage meeles, et Dynamics AX-is on klassihierarhiate nimetamise kokkulepped ja võimalusel on alati hea neid järgida).
Nüüd, kui olete oma klassid kaunistanud, et tuvastada, millist töötlemist igaüks neist teeb, saate kasutada SysExtensioni raamistikku, et alamklasside objekte vajaduse korral luua.
Oma superklassis (MyProcessor) saate lisada sellise konstruktsioonimeetodi:
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;
}
Tõeliselt huvitav osa – ja tegelikult kogu selle postituse objekt (vabandage sõnamängu) – on SysExtensionAppClassFactory klassi meetod getClassFromSysAttribute(). See meetod aktsepteerib hierarhia superklassi nime (ja see superklass ei pea olema hierarhia tipus ; see tähendab lihtsalt, et sobivad on ainult seda klassi laiendavad klassid) ja atribuudiobjekti.
Seejärel tagastab see klassi objekti, mis laiendab määratud superklassi ja on kaunistatud vastava atribuudiga.
Ilmselgelt saate konstrueerimismeetodile lisada nii palju täiendavat valideerimist või loogikat, kui soovite, kuid oluline on see, et pärast rakendamist ei peaks te seda meetodit enam kunagi muutma. Saate lisada hierarhiasse alamklasse ja seni, kuni olete need korralikult kaunistanud, leiab konstruktsioonimeetod need üles isegi siis, kui neid kirjutamise ajal ei eksisteerinud.
Aga jõudlus? Ma ei ole ausalt öeldes proovinud seda võrrelda, kuid minu sisetunne ütleb, et see toimib tõenäoliselt halvemini kui klassikaline lüliti kujundus. Arvestades aga, et Dynamics AX-i jõudlusprobleemid on ülekaalukalt põhjustatud andmebaasidele juurdepääsust, ei muretseks ma selle pärast liiga palju.
Muidugi, kui rakendate midagi, mis nõuab tuhandete objektide kiiret loomist, võiksite uurida lähemalt, kuid klassikalistel juhtudel, kui te lihtsalt loote ühe objekti pikaks töötlemiseks, kahtlen, kas see on oluline. Arvestades ka minu veaotsingu näpunäidet (järgmine lõik), näib, et SysExtensioni raamistik tugineb vahemällu salvestamisele, nii et töötavas süsteemis kahtlen, et sellel on märkimisväärne jõudlus. Veaotsing: kui konstruktsioonimeetod ei leia teie alamklasse, kuigi olete kindel, et need on õigesti kaunistatud, võib see olla vahemällu salvestamise probleem. Proovige vahemälu tühjendada nii kliendis kui ka serveris. AOS-i taaskäivitamine ei tohiks olla vajalik, kuid see võib olla viimane abinõu.