Miklix

„SysExtension Framework“ naudojimas norint sužinoti, kurį poklasį reikia sukurti „Dynamics AX 2012“

Paskelbta: 2025 m. vasario 16 d. 00:25:50 UTC
Paskutinį kartą atnaujinta: 2026 m. sausio 12 d. 08:43:05 UTC

Šiame straipsnyje aprašoma, kaip naudoti mažai žinomą „SysExtension“ sistemą „Dynamics AX 2012“ ir „Dynamics 365 for Operations“, kad būtų galima sukurti poklasius pagal atributų dekoracijas, leidžiant lengvai išplėsti apdorojimo klasių hierarchijos dizainą.


Šis puslapis buvo mašininiu būdu išverstas iš anglų kalbos, kad juo galėtų naudotis kuo daugiau žmonių. Deja, mašininis vertimas dar nėra tobula technologija, todėl gali pasitaikyti klaidų. Jei pageidaujate, originalią versiją anglų kalba galite peržiūrėti čia:

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

Šiame įraše pateikta informacija pagrįsta „Dynamics AX 2012 R3“. Ji gali tikti kitoms versijoms, o gali ir netikti. (Atnaujinimas: galiu patvirtinti, kad šiame straipsnyje pateikta informacija taip pat tinka „Dynamics 365 for Operations“)

Įdiegiant apdorojimo klases „Dynamics AX“, dažnai susiduriama su klasių hierarchijos kūrimu, kurioje kiekvienas poklasis atitinka išvardijimo reikšmę arba turi kitą duomenų sąsają. Klasikinis dizainas yra tada turėti konstrukto metodą superklasėje, kurioje yra jungiklis, kuris nustato, kurią klasę sukurti pagal įvestį.

Iš principo tai veikia gerai, bet jei yra daug skirtingų galimų įvesčių (daug elementų sąraše arba galbūt įvestis yra kelių skirtingų reikšmių derinys), tai gali tapti nuobodu ir klaidų kupina, o projektas visada turi trūkumą, kad jums reikės modifikuoti minėtą konstrukto metodą, jei kada nors pridėsite naują poklasį arba pakeisite, kuris poklasis turėtų būti naudojamas pagal kurį įvestį.

Laimei, yra daug elegantiškesnis, bet, deja, ir daug mažiau žinomas būdas tai padaryti, būtent naudojant „SysExtension“ sistemą.

Ši sistema naudoja atributus, kuriuos galite naudoti savo subklasėms dekoruoti, kad sistema galėtų išsiaiškinti, kuri subklasė turėtų būti naudojama kam tvarkyti. Jums vis tiek reikės konstrukto metodo, bet jei jis bus atliktas teisingai, jums niekada nereikės jo modifikuoti pridedant naujas subklases.

Pažvelkime į įsivaizduojamą pavyzdį ir tarkime, kad ketinate įdiegti hierarchiją, kuri atlieka tam tikrą apdorojimą pagal lentelę „InventTrans“. Kurį apdorojimą atlikti, priklauso nuo įrašų „StatusReceipt“ ir „StatusIssue“, taip pat nuo to, ar įrašai susiję su „SalesLine“, „PurchLine“, ar nė su viena iš jų. Jau dabar matote daug skirtingų derinių.

Tarkime, kad žinote, jog kol kas jums reikia apdoroti tik kelis derinius, bet taip pat žinote, kad laikui bėgant jūsų bus prašoma apdoroti vis daugiau ir daugiau derinių.

Pabandykime paprastai ir tarkime, kad kol kas jums reikia tvarkyti tik su „SalesLine“ susijusius įrašus, kurių „StatusIssue“ yra „ReservPhysical“ arba „ReservOrdered“. Visus kitus derinius kol kas galima ignoruoti, tačiau kadangi žinote, kad juos turėsite tvarkyti vėliau, kodą turėtumėte sukurti taip, kad jį būtų lengva išplėsti.

Jūsų hierarchija kol kas gali atrodyti maždaug taip:

  • ManoProcesoriusManoProcesoriaus_PardavimaiManoProcesoriaus_Pardavimo_RezervasUžsakytasManoProcesoriaus_Pardavimo_RezervasPhysical

Dabar superklasėje galite lengvai įdiegti metodą, kuris sukuria poklasio egzempliorių pagal „ModuleInventPurchSales“ ir „StatusIssue“ išvardijimus. Tačiau tada kiekvieną kartą pridedant poklasį reikės modifikuoti superklasę, o tai nėra paveldėjimo idėja objektinio programavimo srityje. Juk nereikia modifikuoti „RunBaseBatch“ ar „SysOperationServiceBase“ kiekvieną kartą pridedant naują paketinę užduotį.

Vietoj to galite naudoti „SysExtension“ sistemą. Tam reikės pridėti dar vieną klasę, kuri turi išplėsti „SysAttribute“. Ši klasė bus naudojama kaip atributas, kuriuo galėsite papuošti savo apdorojimo klases.

Ši klasė labai panaši į tai, kaip sukurtumėte duomenų sutarties klasę „SysOperation“ diegimui, nes joje bus keli duomenų nariai ir „parm“ metodai šioms reikšmėms gauti ir nustatyti.

Mūsų atveju, klasės deklaracija gali atrodyti maždaug taip:

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

Jums reikia sukurti new() metodą visų duomenų elementų egzemplioriams sukurti. Jei norite, galite kai kuriems arba visiems jiems suteikti numatytąsias reikšmes, bet aš to nedariau.

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

    super();

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

Taip pat turėtumėte įdiegti parm metodą kiekvienam duomenų nariui, bet aš jų čia praleidau, nes esu tikras, kad žinote, kaip tai padaryti – kitu atveju, laikykime tai pratimu ;-)

Dabar galite naudoti savo atributų klasę kiekvienai apdorojimo klasei papuošti. Pavyzdžiui, klasių deklaracijos galėtų atrodyti taip:

[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
{
}

Žinoma, galite pavadinti savo klases kaip tik norite, svarbiausia, kad jas pavadintumėte atributais, atitinkančiais jų atliekamą apdorojimo procesą. (Tačiau atminkite, kad „Dynamics AX“ klasių hierarchijoms taikomos pavadinimų suteikimo konvencijos ir, jei įmanoma, visada pravartu jų laikytis).

Dabar, kai jau surūšiavote savo klases, kad nustatytumėte, kokį apdorojimą kiekviena iš jų atlieka, galite pasinaudoti „SysExtension“ sistema, kad prireikus sukurtumėte subklasių objektų egzempliorius.

Savo superklasėje („MyProcessor“) galite pridėti tokį konstrukto metodą:

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;
}

Išties įdomi dalis – ir iš tikrųjų viso šio įrašo objektas (atsiprašau už kalambūrą) – yra „SysExtensionAppClassFactory“ klasės metodas „getClassFromSysAttribute()“. Šis metodas priima hierarchijos superklasės pavadinimą (ir ši superklasė nebūtinai turi būti hierarchijos viršuje; tai tiesiog reiškia, kad tinka tik šią klasę išplečiančios klasės) ir atributo objektą.

Tada grąžina klasės objektą, kuris išplečia nurodytą superklasę ir yra papuoštas atitinkamu atributu.

Žinoma, galite pridėti tiek papildomo patvirtinimo ar logikos prie „construct“ metodo, kiek norite, tačiau svarbiausia išvada yra ta, kad įdiegus šį metodą, jo daugiau niekada nereikėtų modifikuoti. Galite pridėti poklasius prie hierarchijos ir tol, kol tinkamai juos papuošite, „construct“ metodas jas ras, net jei jų nebuvo rašymo metu.

Kaip dėl našumo? Sąžiningai, nebandžiau atlikti lyginamosios analizės, bet nuojauta rodo, kad šis metodas tikriausiai veikia prasčiau nei klasikinis perjungimo sakinio dizainas. Tačiau atsižvelgiant į tai, kad dauguma „Dynamics AX“ našumo problemų kyla dėl prieigos prie duomenų bazės, per daug dėl to nesijaudinčiau.

Žinoma, jei diegiate kažką, kam reikės greitai sukurti tūkstančius objektų, galite pabandyti atlikti išsamesnį tyrimą, tačiau klasikiniais atvejais, kai sukuriate tik vieną objektą ilgam apdorojimui, abejoju, ar tai bus svarbu. Be to, atsižvelgiant į mano trikčių šalinimo patarimą (kita pastraipa), atrodo, kad „SysExtension“ sistema remiasi talpykla, todėl abejoju, ar veikiančioje sistemoje ji turi didelį našumo sumažėjimą.

Trikčių šalinimas: Jei konstrukto metodas neranda jūsų poklasių, net jei esate tikri, kad jos tinkamai išdėstytos, tai gali būti talpyklos problema. Pabandykite išvalyti talpyklas tiek kliento, tiek serverio įrenginiuose. Neturėtų reikėti iš naujo paleisti AOS, tačiau tai gali būti kraštutinė priemonė.

Papildoma literatūra

Jei jums patiko šis įrašas, jums taip pat gali patikti šie pasiūlymai:


Pasidalinkite „Bluesky“.Dalintis FacebookBendrinkite „LinkedIn“.Bendrinkite „Tumblr“.Dalintis XBendrinkite „LinkedIn“.Prisegti prie Pinterest

Mikkel Christensen

Apie autorių

Mikkel Christensen
Mikkelis yra miklix.com kūrėjas ir savininkas. Jis turi daugiau nei 20 metų profesionalaus kompiuterių programuotojo ir programinės įrangos kūrėjo patirtį ir šiuo metu visą darbo dieną dirba didelėje Europos IT korporacijoje. Kai jis nerašo tinklaraščio, laisvalaikį skiria įvairiems interesams, pomėgiams ir užsiėmimams, kurie tam tikra prasme gali atsispindėti šioje svetainėje nagrinėjamų temų įvairovėje.