SysExtension Framework izmantošana, lai uzzinātu, kuru apakšklasi iemiesot programmā Dynamics AX 2012
Publicēts: 2025. gada 16. februāris 00:25:51 UTC
Pēdējo reizi atjaunināts: 2026. gada 12. janvāris 08:43:06 UTC
Šajā rakstā ir aprakstīts, kā izmantot mazpazīstamo SysExtension platformu Dynamics AX 2012 un Dynamics 365 for Operations, lai izveidotu apakšklases, pamatojoties uz atribūtu dekorācijām, tādējādi nodrošinot viegli paplašināmu apstrādes klases hierarhijas dizainu.
Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012
Šajā ierakstā sniegtā informācija ir balstīta uz Dynamics AX 2012 R3. Tā var būt vai nebūt derīga citām versijām. (Atjauninājums: varu apstiprināt, ka šajā rakstā sniegtā informācija ir derīga arī Dynamics 365 for Operations).
Ieviešot apstrādes klases programmā Dynamics AX, bieži nākas veidot klases hierarhiju, kurā katra apakšklase atbilst uzskaitījuma vērtībai vai tai ir kāda cita datu saistīšana. Klasisks risinājums ir izveidot konstrukcijas metodi superklasē, kurai ir slēdzis, kas nosaka, kuru klasi izveidot, pamatojoties uz ievadi.
Principā tas darbojas labi, bet, ja ir daudz dažādu iespējamo ievades datu (daudzi elementi uzskaitījumā vai varbūt ievades dati ir vairāku dažādu vērtību kombinācija), to var kļūt nogurdinoši un kļūdaini uzturēt, un šim dizainam vienmēr ir trūkums, ka jums būs jāmodificē minētā konstrukcijas metode, ja kādreiz pievienosiet jaunu apakšklasi vai veiksiet izmaiņas tajā, kura apakšklase jāizmanto, pamatojoties uz kuru ievades datu kopu.
Par laimi, ir daudz elegantāks, bet diemžēl arī daudz mazāk zināms veids, kā to izdarīt, proti, izmantojot SysExtension ietvaru.
Šis ietvars izmanto atribūtus, kurus var izmantot apakšklases dekorēšanai, lai sistēma spētu noteikt, kura apakšklase jāizmanto ko apstrādei. Jums joprojām būs nepieciešama konstrukcijas metode, taču, ja tā tiks izdarīta pareizi, tā nekad nebūs jāmaina, pievienojot jaunas apakšklases.
Apskatīsim iedomātu piemēru, kurā ieviesīsiet hierarhiju, kas veic kaut kādu apstrādi, pamatojoties uz tabulu InventTrans. Kura apstrāde jāveic, ir atkarīga no ierakstu StatusReceipt un StatusIssue, kā arī no tā, vai ieraksti ir saistīti ar SalesLine, PurchLine vai nevienu no tiem. Jau tagad jūs aplūkojat daudz dažādu kombināciju.
Tad pieņemsim, ka jūs zināt, ka pagaidām jums ir jāapstrādā tikai dažas no kombinācijām, bet jūs arī zināt, ka laika gaitā jums tiks lūgts spēt apstrādāt arvien vairāk kombināciju.
Saglabāsim to relatīvi vienkāršu un pieņemsim, ka pagaidām jums ir jāapstrādā tikai ieraksti, kas saistīti ar SalesLine ar StatusIssue vērtību ReservPhysical vai ReservOrdered, visas pārējās kombinācijas pagaidām var ignorēt, bet, tā kā jūs zināt, ka jums tās būs jāapstrādā vēlāk, jums vajadzētu izstrādāt savu kodu tā, lai to būtu viegli paplašināt.
Jūsu hierarhija pagaidām varētu izskatīties apmēram šādi:
- MansProcesorsMansProcesors_PārdošanaMansProcesors_Pārdošanas_RezervePasūtītsMansProcesors_Pārdošanas_RezerveFiziskais
Tagad superklasē varētu viegli ieviest metodi, kas izveido apakšklases instanci, pamatojoties uz ModuleInventPurchSales un StatusIssue uzskaitījumu. Taču tad jums būs jāmodificē superklase katru reizi, kad pievienosiet apakšklasi, un tā īsti nav mantošanas ideja objektorientētā programmēšanā. Galu galā, jums nav jāmodificē RunBaseBatch vai SysOperationServiceBase katru reizi, kad pievienojat jaunu pakešuzdevumu.
Tā vietā varat izmantot SysExtension ietvaru. Tas prasīs pievienot vēl vienu klasi, kurai jāpaplašina SysAttribute. Šī klase tiks izmantota kā atribūts, ar kuru varēsiet dekorēt savas apstrādes klases.
Šī klase ir ļoti līdzīga tam, kā jūs izveidotu datu līguma klasi SysOperation ieviešanai, jo tai būs daži datu elementi un parm metodes šo vērtību iegūšanai un iestatīšanai.
Mūsu gadījumā klases deklarācija varētu izskatīties apmēram šādi:
{
ModuleInventPurchSales module;
StatusIssue statusIssue;
StatusReceipt statusReceipt
}
Jums ir jāizveido new() metode visu datu elementu instancēšanai. Ja vēlaties, varat dažiem vai visiem tiem piešķirt noklusējuma vērtības, bet es to neesmu izdarījis.
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
;
super();
module = _module;
statusIssue = _statusIssue;
statusReceipt = _statusReceipt;
}
Un jums vajadzētu arī ieviest parm metodi katram datu elementam, bet es tās šeit neesmu pieminējis, jo esmu pārliecināts, ka jūs zināt, kā to izdarīt — pretējā gadījumā uzskatīsim to par vingrinājumu ;-)
Tagad jūs varat izmantot savu atribūtu klasi, lai dekorētu katru no savām apstrādes klasēm. Piemēram, klases deklarācijas varētu izskatīties šādi:
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
{
}
Protams, klases var nosaukt, kā vien vēlaties, taču svarīgākais ir tas, lai klases tiktu apzīmētas ar atribūtiem, kas atbilst to apstrādes veidam. (Taču paturiet prātā, ka Dynamics AX klašu hierarhijām ir nosaukumu piešķiršanas konvencijas, un, ja iespējams, vienmēr ir ieteicams tās ievērot.)
Tagad, kad esat noformulējis savas klases, lai noteiktu, kāda veida apstrādi katra no tām veic, varat izmantot SysExtension ietvaru, lai pēc nepieciešamības izveidotu apakšklašu objektu instances.
Savā superklasē (MyProcessor) jūs varētu pievienot šādu konstrukcijas metodi:
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;
}
Patiešām interesantākā daļa — un patiesībā visas šīs ziņas objekts (atvainojiet par vārdu spēli) — ir SysExtensionAppClassFactory klases metode getClassFromSysAttribute(). Šī metode pieņem hierarhijas superklases nosaukumu (un šai superklasei nav jāatrodas hierarhijas augšgalā; tas vienkārši nozīmē, ka tikai klases, kas paplašina šo klasi, būs tiesīgas to izmantot) un atribūta objektu.
Pēc tam tas atgriež klases objektu, kas paplašina norādīto superklasi un ir dekorēts ar atbilstošu atribūtu.
Protams, jūs varat pievienot metodei "construct" tik daudz papildu validācijas vai loģikas, cik vēlaties, taču svarīgākais ir tas, ka pēc ieviešanas šī metode vairs nekad nebūs jāmaina. Hierarhijai var pievienot apakšklases, un, ja vien jūs tās atbilstoši noformēsiet, metode "construct" tās atradīs, pat ja tās nepastāvēja metodes rakstīšanas brīdī.
Kā ar veiktspēju? Godīgi sakot, es neesmu mēģinājis to salīdzināt, bet mana intuīcija liek domāt, ka šī funkcija, iespējams, darbojas sliktāk nekā klasiskā slēdža priekšraksta konstrukcija. Tomēr, ņemot vērā, ka lielāko daļu veiktspējas problēmu Dynamics AX sistēmā rada piekļuve datubāzei, es par to pārāk neuztrauktos.
Protams, ja ieviešat kaut ko tādu, kam būs nepieciešams ātri izveidot tūkstošiem objektu, iespējams, vēlēsities veikt sīkāku izpēti, taču klasiskajos gadījumos, kad ilgstošas apstrādes veikšanai tiek izveidots tikai viens objekts, es šaubos, vai tam būs nozīme. Turklāt, ņemot vērā manu problēmu novēršanas padomu (nākamā rindkopa), šķiet, ka SysExtension ietvars balstās uz kešatmiņu, tāpēc darbojošās sistēmā es šaubos, vai tam ir būtisks veiktspējas kritums.
Problēmu novēršana: Ja konstruēšanas metode neatrod jūsu apakšklases, pat ja esat pārliecināts, ka tās ir pareizi noformētas, iespējams, tā ir kešatmiņas problēma. Mēģiniet notīrīt kešatmiņu gan klientā, gan serverī. AOS restartēšanai nevajadzētu būt nepieciešamai, taču tā varētu būt pēdējā iespēja.
Papildu lasāmviela
Ja jums patika šī ziņa, jums varētu patikt arī šie ieteikumi:
- Atšķirība starp data() un buf2Buf() programmā Dynamics AX 2012
- Virknes formatēšana, izmantojot makro un strFmt programmā Dynamics AX 2012
- Kā atkārtot Enum elementus no X++ koda programmā Dynamics AX 2012
