Miklix

A SysExtension Framework segítségével megtudhatja, melyik alosztályt kell példányosítani a Dynamics AX 2012-ben

Megjelent: 2025. február 16. 0:25:42 UTC
Utolsó frissítés: 2026. január 12. 8:43:00 UTC

Ez a cikk leírja, hogyan használható a kevéssé ismert SysExtension keretrendszer a Dynamics AX 2012 és a Dynamics 365 for Operations rendszerekben alkategóriák attribútumdekorációk alapján történő példányosítására, lehetővé téve a feldolgozási osztályhierarchia könnyen bővíthető kialakítását.


Ezt az oldalt angolból gépi fordítással készítettük, hogy minél több ember számára elérhető legyen. Sajnos a gépi fordítás még nem tökéletes technológia, ezért előfordulhatnak hibák. Ha szeretné, itt megtekintheti az eredeti angol nyelvű változatot:

Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012

A bejegyzésben szereplő információk a Dynamics AX 2012 R3 rendszeren alapulnak. Előfordulhat, hogy más verziókra érvényesek. (Frissítés: Megerősíthetem, hogy a cikkben szereplő információk a Dynamics 365 for Operations rendszerre is érvényesek.)

Dynamics AX feldolgozási osztályainak implementálásakor gyakran szembesülünk egy olyan osztályhierarchia létrehozásával, amelyben minden alosztály egy enumerációs értéknek felel meg, vagy valamilyen más adatkapcsolattal rendelkezik. Egy klasszikus kialakítás szerint ezután a szuperosztályban van egy construct metódus, amelynek van egy kapcsolója, amely meghatározza, hogy melyik osztályt kell példányosítani a bemenet alapján.

Ez elvileg jól működik, de ha sok különböző lehetséges bemeneted van (sok elem egy enumban, vagy esetleg a bemenet több különböző érték kombinációja), akkor a karbantartása unalmassá és hibára hajlamossá válhat, és a tervezésnek mindig megvan az a hátránya, hogy módosítanod kell az említett konstrukciós metódust, ha valaha új alosztályt adsz hozzá, vagy megváltoztatod, hogy melyik alosztályt melyik bemenet alapján kell használni.

Szerencsére létezik egy sokkal elegánsabb, de sajnos sokkal kevésbé ismert módja ennek, nevezetesen a SysExtension keretrendszer használata.

Ez a keretrendszer olyan attribútumokat használ, amelyekkel az alosztályokat díszítheted, hogy a rendszer képes legyen kitalálni, melyik alosztályt mit kell használni. Továbbra is szükség lesz egy konstrukciós metódusra, de ha helyesen csinálod, akkor soha nem kell módosítanod új alosztályok hozzáadásakor.

Nézzünk egy képzeletbeli példát, és tegyük fel, hogy egy olyan hierarchiát fogsz megvalósítani, amely valamilyen feldolgozást végez az InventTrans tábla alapján. Az, hogy melyik feldolgozást kell elvégezni, a rekordok StatusReceipt és StatusIssue értékétől, valamint attól függ, hogy a rekordok a SalesLine-hoz, a PurchLine-hoz vagy egyikhez sem kapcsolódnak-e. Már most is számos különböző kombinációt vizsgálunk.

Tegyük fel akkor, hogy tudod, hogy egyelőre csak néhány kombinációt kell kezelned, de azt is tudod, hogy idővel egyre több kombináció kezelésére leszel képes.

Tartsuk viszonylag egyszerűen, és tegyük fel, hogy egyelőre csak a ReservPhysical vagy ReservOrdered StatusIssue értékű SalesLine-hoz kapcsolódó rekordokat kell kezelni, minden más kombinációt egyelőre figyelmen kívül hagyhatunk, de mivel tudjuk, hogy később kezelni kell őket, a kódot úgy kell megtervezni, hogy könnyen bővíthető legyen.

A hierarchiád egyelőre így nézhet ki:

  • SajátFolyamatosMyProcessorMyProcessor_SalesMyProcessor_Sales_ReservOrderedMyProcessor_Sales_ReservPhysical

Most könnyen implementálhatsz egy metódust a szuperosztályban, amely egy ModuleInventPurchSales és egy StatusIssue enum alapján példányosít egy alosztályt. De ekkor minden alkalommal módosítanod kell a szuperosztályt, amikor hozzáadsz egy alosztályt, és ez nem igazán az öröklődés alapja az objektumorientált programozásban. Végül is nem kell módosítanod a RunBaseBatch vagy a SysOperationServiceBase metódusokat minden alkalommal, amikor új kötegelt feldolgozást adsz hozzá.

Ehelyett használhatod a SysExtension keretrendszert. Ehhez egy másik osztályt kell hozzáadnod, amelynek ki kell terjesztenie a SysAttribute-ot. Ezt az osztályt fogod használni attribútumként, amellyel a feldolgozó osztályaidat díszítheted.

Ez az osztály nagyon hasonlít ahhoz, ahogyan egy SysOperation implementációhoz létrehoznánk egy adatszerződési osztályt, abban az értelemben, hogy tartalmaz néhány adattagot és parm metódust ezen értékek lekéréséhez és beállításához.

A mi esetünkben az Osztálydeklaráció valahogy így nézhet ki:

class MyProcessorSystemAttribute extends SysAttribute
{
    ModuleInventPurchSales  module;
    StatusIssue             statusIssue;
    StatusReceipt           statusReceipt
}

Létre kell hoznod egy new() metódust az összes adattag példányosításához. Ha szeretnéd, megadhatsz néhányuknak vagy mindegyiknek alapértelmezett értéket, de én ezt még nem tettem meg.

public void new(ModuleInventPurchSales  _module,
                StatusIssue             _statusIssue,
                StatusReceipt           _statusReceipt)
{
    ;

    super();

    module          = _module;
    statusIssue     = _statusIssue;
    statusReceipt   = _statusReceipt;
}

És minden egyes adattaghoz implementálnod kellene egy parm metódust is, de ezeket itt kihagytam, mert biztos vagyok benne, hogy tudod, hogyan kell - egyébként tekintsük gyakorlatnak ;-)

Most már használhatod az attribútumosztályodat az egyes feldolgozási osztályok díszítésére. Például az osztálydeklarációk így nézhetnek ki:

[MyProcessorSystemAttribute(ModuleInventPurchSales::Sales,
                            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
{
}

Természetesen az osztályokat bármilyen módon elnevezheted, a lényeg az, hogy olyan attribútumokkal lássad el őket, amelyek megfelelnek annak, hogy milyen feldolgozást végeznek. (De ne feledd, hogy a Dynamics AX-ben vannak elnevezési konvenciók az osztályhierarchiákra, és mindig érdemes ezeket betartani, ha lehetséges).

Most, hogy az osztályokat úgy definiáltad, hogy azonosítsd, milyen feldolgozást végeznek, kihasználhatod a SysExtension keretrendszer előnyeit az alosztályok objektumainak szükség szerinti példányosításához.

A szuperosztályodban (MyProcessor) hozzáadhatsz egy ilyen konstrukciós metódust:

public static MyProcessor construct(ModuleInventPurchSales _module,
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;
}

Az igazán érdekes rész – és igazából az egész bejegyzés objektuma (elnézést a szójátékért) – a SysExtensionAppClassFactory osztály getClassFromSysAttribute() metódusa. Ez a metódus elfogadja egy hierarchia szuperosztályának nevét (és ennek a szuperosztálynak nem kell a hierarchia tetején lennie; ez egyszerűen azt jelenti, hogy csak az ezt az osztályt kiterjesztő osztályok lesznek jogosultak) és egy attribútumobjektumot.

Ezután egy olyan osztály objektumát adja vissza, amely kiterjeszti a megadott szuperosztályt, és egy megfelelő attribútummal van ellátva.

Nyilvánvalóan annyi további validációt vagy logikát adhatsz a construct metódushoz, amennyit csak szeretnél, de a lényeg az, hogy implementálás után soha többé nem kell módosítanod ezt a metódust. Hozzáadhatsz alkategóriákat a hierarchiához, és amíg megfelelően díszíted őket, a construct metódus meg fogja találni őket, még akkor is, ha nem léteztek a metódus írásakor.

Mi a helyzet a teljesítménnyel? Őszintén szólva nem próbáltam összehasonlítani, de a megérzésem az, hogy ez valószínűleg rosszabbul teljesít, mint a klasszikus switch utasításdizájn. Azonban figyelembe véve, hogy a Dynamics AX-ben messze a legtöbb teljesítményproblémát az adatbázis-hozzáférés okozza, nem aggódnék emiatt túlságosan.

Természetesen, ha olyasmit valósítasz meg, ami több ezer objektum gyors létrehozását igényli, érdemes lehet tovább vizsgálódni, de a klasszikus esetekben, amikor csak egyetlen objektumot példányosítasz valamilyen hosszadalmas feldolgozáshoz, kétlem, hogy ez számítana. Továbbá, figyelembe véve a hibaelhárítási tippemet (következő bekezdés), úgy tűnik, hogy a SysExtension keretrendszer gyorsítótárazásra támaszkodik, így egy futó rendszerben kétlem, hogy jelentős teljesítménycsökkenést eredményezne.

Hibaelhárítás: Ha a construct metódus nem találja az alosztályokat, annak ellenére, hogy biztos vagy benne, hogy helyesen vannak dekorálva, akkor gyorsítótárazási probléma lehet. Próbáld meg törölni a gyorsítótárat mind a kliens, mind a szerver oldalon. Nem feltétlenül szükséges újraindítani az AOS-t, de ez lehet a végső megoldás.

További olvasmányok

Ha tetszett ez a bejegyzés, akkor ezek a javaslatok is érdekelhetik:


Oszd meg a Bluesky-nOszd meg a FacebookonOszd meg a LinkedIn-enOszd meg a Tumblr-enOszd meg X-enOszd meg a LinkedIn-enPin a Pinteresten

Mikkel Christensen

A szerzőről

Mikkel Christensen
Mikkel a miklix.com létrehozója és tulajdonosa. Több mint 20 éves tapasztalattal rendelkezik, mint hivatásos számítógépes programozó/szoftverfejlesztő, és jelenleg teljes munkaidőben dolgozik egy nagy európai informatikai vállalatnál. Amikor nem blogol, szabadidejét érdeklődési körének, hobbijainak és tevékenységeinek széles skálájával tölti, ami bizonyos mértékig tükröződhet a weboldalon tárgyalt témák sokféleségében.