Korištenje SysExtension frameworka da biste saznali koju podklasu instancirati u Dynamics AX 2012
Objavljeno: 16. februar 2025. u 00:28:17 UTC
Posljednje ažurirano: 12. januar 2026. u 08:43:40 UTC
Ovaj članak opisuje kako koristiti malo poznati SysExtension okvir u Dynamics AX 2012 i Dynamics 365 for Operations za instanciranje podklasa na osnovu dekoracija atributa, što omogućava lako proširiv dizajn hijerarhije klasa obrade.
Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012
Informacije u ovom postu zasnovane su na Dynamics AX 2012 R3. Mogu, ali i ne moraju biti važeće za druge verzije. (Ažuriranje: Mogu potvrditi da informacije u ovom članku vrijede i za Dynamics 365 for Operations)
Prilikom implementacije klasa za obradu u Dynamics AX-u, često se suočavate s kreiranjem hijerarhije klasa u kojoj svaka podklasa odgovara vrijednosti nabrajanja ili ima neko drugo povezivanje podataka. Klasičan dizajn je da se zatim u nadklasi ima metoda konstrukcije, koja ima prekidač koji određuje koju klasu treba instancirati na osnovu ulaza.
Ovo u principu dobro funkcioniše, ali ako imate mnogo različitih mogućih ulaza (mnogo elemenata u nabrojavanju ili je možda ulaz kombinacija nekoliko različitih vrijednosti), održavanje može postati zamorno i sklono greškama, a dizajn uvijek ima nedostatak da ćete morati modificirati navedenu metodu konstrukcije ako ikada dodate novu podklasu ili napravite promjene u tome koja podklasa treba da se koristi na osnovu kojeg ulaza.
Srećom, postoji mnogo elegantniji, ali nažalost i mnogo manje poznat način da se to uradi, naime korištenjem SysExtension okvira.
Ovaj okvir koristi atribute koje možete koristiti za ukrašavanje svojih podklasa kako bi sistem mogao odrediti koja podklasa treba da se koristi za rukovanje čim. I dalje će vam trebati metoda konstrukta, ali ako se uradi ispravno, nikada je nećete morati mijenjati prilikom dodavanja novih podklasa.
Pogledajmo zamišljeni primjer i recimo da ćete implementirati hijerarhiju koja vrši neku vrstu obrade na osnovu tabele InventTrans. Koja obrada će se izvršiti zavisi od StatusReceipt i StatusIssue zapisa, kao i od toga da li su zapisi povezani sa SalesLine, PurchLine ili nijednim. Već sada vidite mnogo različitih kombinacija.
Recimo da znate da za sada trebate obraditi samo nekoliko kombinacija, ali također znate da će se od vas s vremenom tražiti da budete u stanju obraditi sve više i više kombinacija.
Recimo da je relativno jednostavno i da za sada trebate obrađivati samo zapise povezane sa SalesLine sa StatusIssue vrijednostima ReservPhysical ili ReservOrdered, sve ostale kombinacije se za sada mogu zanemariti, ali budući da znate da ćete ih morati obraditi kasnije, poželjet ćete dizajnirati svoj kod na način koji ga čini lako proširivim.
Vaša hijerarhija bi za sada mogla izgledati ovako:
- MojProcesorMojProcesor_ProdajaMojaProcesor_Rezerva_ProdajeNaručenoMojaProcesor_Rezerva_ProdajeFizička
Sada biste mogli lako implementirati metodu u nadklasi koja instancira podklasu na osnovu ModuleInventPurchSales i StatusIssue nabrajanja. Ali tada ćete morati mijenjati nadklasu svaki put kada dodate podklasu, a to zapravo nije ideja nasljeđivanja u objektno orijentisanom programiranju. Uostalom, ne morate mijenjati RunBaseBatch ili SysOperationServiceBase svaki put kada dodate novi batch zadatak.
Umjesto toga, možete koristiti SysExtension framework. To će zahtijevati dodavanje još jedne klase koja treba proširiti SysAttribute. Ova klasa će se koristiti kao atribut kojim možete ukrasiti svoje klase za obradu.
Ova klasa je vrlo slična načinu na koji biste napravili klasu ugovora o podacima za implementaciju SysOperation, po tome što će imati neke članove podataka i parm metode za dobijanje i postavljanje tih vrijednosti.
U našem slučaju, ClassDeclaration može izgledati otprilike ovako:
{
ModuleInventPurchSales module;
StatusIssue statusIssue;
StatusReceipt statusReceipt
}
Potrebno je da napravite metodu new() za instanciranje svih članova podataka. Ako želite, možete dati nekim ili svim njima zadane vrijednosti, ali ja to nisam uradio.
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
;
super();
module = _module;
statusIssue = _statusIssue;
statusReceipt = _statusReceipt;
}
Također biste trebali implementirati parm metodu za svaki član podataka, ali sam ih ovdje izostavio jer sam siguran da znate kako to učiniti - u suprotnom, smatrajmo to vježbom ;-)
Sada možete koristiti svoju klasu atributa za ukrašavanje svake od vaših klasa obrade. Na primjer, deklaracije klasa mogu izgledati ovako:
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
{
}
Naravno, možete imenovati svoje klase kako god želite, važno je da ukrasite svoje klase atributima koji odgovaraju vrsti obrade koju obavljaju. (Ali imajte na umu da postoje konvencije imenovanja za hijerarhije klasa u Dynamics AX-u i uvijek je dobra ideja slijediti ih, ako je moguće).
Sada kada ste uredili svoje klase kako biste identifikovali koju vrstu obrade svaka od njih obavlja, možete iskoristiti SysExtension framework za instanciranje objekata podklasa po potrebi.
U vašoj nadklasi (MyProcessor), možete dodati konstruktnu metodu poput ove:
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;
}
Zaista zanimljiv dio - i zapravo cilj (oprostite na igri riječi) cijelog ovog posta - je metoda getClassFromSysAttribute() u klasi SysExtensionAppClassFactory. Ova metoda prihvata ime nadklase hijerarhije (i ova nadklasa ne mora biti na vrhu hijerarhije; to jednostavno znači da će samo klase koje proširuju ovu klasu biti podobne) i objekt atributa.
Zatim vraća objekt klase koja proširuje specificiranu superklasu i dekorirana je odgovarajućim atributom.
Očigledno možete dodati onoliko daljnje validacije ili logike metodi konstrukta koliko želite, ali važna stvar je da, nakon što se implementira, nikada više ne biste trebali mijenjati ovu metodu. Možete dodati podklase hijerarhiji i sve dok se pobrinete da ih pravilno dekorišete, metoda konstrukta će ih pronaći čak i ako nisu postojale kada je napisana.
Šta je s performansama? Iskreno, nisam pokušao da ga uporedim s performansama, ali imam osjećaj da ovo vjerovatno daje lošije rezultate od klasičnog dizajna switch naredbi. Međutim, s obzirom na to da je daleko najviše problema s performansama u Dynamics AX-u uzrokovano pristupom bazi podataka, ne bih se previše brinuo oko toga.
Naravno, ako implementirate nešto što će zahtijevati brzo kreiranje hiljada objekata, možda biste trebali dalje istražiti, ali u klasičnim slučajevima gdje samo instancirate jedan objekt za obavljanje neke dugotrajne obrade, sumnjam da će to biti važno. Također, uzimajući u obzir moj savjet za rješavanje problema (sljedeći paragraf), čini se da se SysExtension framework oslanja na keširanje, tako da u pokrenutom sistemu sumnjam da ima značajan pad performansi.
Rješavanje problema: Ako metoda konstruiranja ne pronađe vaše podklase iako ste sigurni da su ispravno uređene, problem može biti u keširanju. Pokušajte obrisati keširanje i na klijentu i na serveru. Ne bi trebalo biti potrebno ponovo pokrenuti AOS, ali to može biti krajnja opcija.
Dodatno čitanje
Ako vam se svidio ovaj post, možda će vam se svidjeti i ovi prijedlozi:
- Pretvaranje realnog u niz sa svim decimalama u Dynamics AX 2012
- Korištenje upita u klasi ugovora podataka SysOperation u Dynamics AX 2012
- Dynamics AX 2012 SysOperation Framework Brzi pregled
