Miklix

SysExtension Frameworkin käyttäminen Dynamics AX 2012:ssa luotavan alaluokan selvittämiseen

Julkaistu: 16. helmikuuta 2025 klo 0.25.40 UTC

Tässä artikkelissa kuvataan, kuinka vähän tunnettua SysExtension-kehystä käytetään Dynamics AX 2012:ssa ja Dynamics 365 for Operationsissa alaluokkien luomiseen attribuuttien koristelujen perusteella, mikä mahdollistaa käsittelyluokkahierarkian helposti laajennettavan suunnittelun.


Tämä sivu on käännetty koneellisesti englannista, jotta se olisi mahdollisimman monen ihmisen saatavilla. Valitettavasti konekääntäminen ei ole vielä täydellistä tekniikkaa, joten virheitä voi esiintyä. Voit halutessasi tarkastella alkuperäistä englanninkielistä versiota täällä:

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

Tämän viestin tiedot perustuvat Dynamics AX 2012 R3:een. Se voi olla tai ei ole voimassa muille versioille. (Päivitys: Voin vahvistaa, että tämän artikkelin tiedot koskevat myös Dynamics 365 for Operationsia)

Kun toteutat käsittelyluokkia Dynamics AX:ssä, joudut usein luomaan luokkahierarkian, jossa jokainen alaluokka vastaa enum-arvoa tai jolla on jokin muu datakytkentä. Klassisen mallin mukaan superluokassa on sitten konstruktiomenetelmä, jossa on kytkin, joka määrittää, mikä luokka instantioidaan syötteen perusteella.

Tämä toimii periaatteessa hyvin, mutta jos sinulla on monia erilaisia ​​mahdollisia syötteitä (monia elementtejä enumissa tai syöte on ehkä useiden eri arvojen yhdistelmä), sen ylläpito voi olla tylsää ja virhealtista, ja suunnittelussa on aina se haittapuoli, että joudut muokkaamaan mainittua rakennusmenetelmää, jos lisäät uuden alaluokan tai teet muutoksia mihin alaluokkaan tulee käyttää minkä syötteen perusteella.

Onneksi on olemassa paljon tyylikkäämpi, mutta valitettavasti myös vähemmän tunnettu tapa tehdä tämä, nimittäin SysExtension-kehystä.

Tämä kehys hyödyntää attribuutteja, joita voit käyttää alaluokkien koristeluun, jotta järjestelmä pystyy selvittämään, mitä alaluokkaa tulisi käyttää käsittelemään mitä. Tarvitset silti konstruktiomenetelmän, mutta jos se tehdään oikein, sinun ei koskaan tarvitse muokata sitä, kun lisäät uusia alaluokkia.

Katsotaanpa kuvitteellista esimerkkiä ja sanotaan, että aiot ottaa käyttöön hierarkian, joka suorittaa jonkinlaisen käsittelyn InventTrans-taulukon perusteella. Tehtävä käsittely riippuu tietueiden StatusReceipt- ja StatusIssue-arvoista sekä siitä, liittyvätkö tietueet SalesLine-, PurchLine- tai ei kumpaankaan. Katselet jo nyt monia erilaisia ​​yhdistelmiä.

Oletetaan sitten, että tiedät, että toistaiseksi sinun tarvitsee käsitellä vain kourallinen yhdistelmiä, mutta tiedät myös, että sinua pyydetään pystymään käsittelemään yhä useampia yhdistelmiä ajan myötä.

Pidetään se suhteellisen yksinkertaisena ja sanotaan, että toistaiseksi sinun tarvitsee käsitellä vain SalesLinen tietueita, joiden StatusIssue on ReservPhysical tai ReservOrdered, kaikki muut yhdistelmät voidaan toistaiseksi jättää huomiotta, mutta koska tiedät, että sinun on käsiteltävä niitä myöhemmin, sinun kannattaa suunnitella koodisi siten, että se on helposti laajennettavissa.

Hierarkiasi voi näyttää tällä hetkellä tältä:

  • MyProcessor
    • MyProcessor_Sales
      • MyProcessor_Sales_ReservOrdered
      • MyProcessor_Sales_ReservPhysical

Nyt voit helposti toteuttaa superluokassa menetelmän, joka luo aliluokan ModuleInventPurchSales- ja StatusIssue-enumiin perustuen. Mutta sinun on sitten muokattava superluokkaa joka kerta, kun lisäät aliluokan, eikä se oikeastaan ​​ole periytymisen idea olio-ohjelmoinnissa. Loppujen lopuksi sinun ei tarvitse muokata RunBaseBatch- tai SysOperationServiceBasea joka kerta, kun lisäät uuden erätyön.

Sen sijaan voit käyttää SysExtension-kehystä. Tämä edellyttää, että lisäät toisen luokan, jonka on laajennettava SysAttributea. Tätä luokkaa käytetään attribuuttina, jolla voit koristella käsittelyluokkasi.

Tämä luokka on hyvin samanlainen kuin tekisit tietosopimusluokan SysOperation-toteutukselle, sillä siinä on joitain datajäseniä ja parm-menetelmiä näiden arvojen saamiseksi ja asettamiseen.

Meidän tapauksessamme ClassDeclaration voi näyttää tältä:

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

Sinun on tehtävä uusi()-menetelmä kaikkien datajäsenten instantoimiseksi. Halutessasi voit antaa osan tai kaikki oletusarvot, mutta en ole tehnyt sitä.

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

    super();

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

Ja sinun pitäisi myös ottaa käyttöön parm-menetelmä jokaiselle datajäsenelle, mutta jätin ne täältä pois, koska tiedät varmasti kuinka se tehdään - muuten katsotaanpa harjoitukseksi ;-)

Nyt voit käyttää attribuuttiluokkaasi jokaisen käsittelyluokkasi koristeluun. Luokkailmoitukset voisivat näyttää esimerkiksi tältä:

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

Voit tietysti nimetä luokkasi haluamallasi tavalla, tärkeintä tässä on, että koristat luokkasi attribuutteilla, jotka vastaavat niiden käsittelyä. (Mutta muista, että Dynamics AX:ssä on luokkahierarkioiden nimeämiskäytäntöjä, ja niitä on aina hyvä noudattaa, jos mahdollista).

Nyt kun olet koristellut luokkasi tunnistamaan, millaista käsittelyä kukin niistä tekee, voit hyödyntää SysExtension-kehystä aliluokkien objektien ilmentämiseen tarpeen mukaan.

Superluokkaasi (MyProcessor) voit lisätä seuraavanlaisen konstruointimenetelmän:

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

Todella mielenkiintoinen osa - ja oikeastaan ​​koko tämän viestin kohde (anteeksi sanapeli) - on SysExtensionAppClassFactory-luokan getClassFromSysAttribute()-metodi. Tämä menetelmä hyväksyy sen, että se hyväksyy hierarkian superluokan nimen (ja tämän superluokan ei tarvitse olla hierarkian huipulla ; se tarkoittaa yksinkertaisesti, että vain tätä luokkaa laajentavat luokat ovat kelvollisia) ja attribuuttiobjektin.

Sitten se palauttaa luokan objektin, joka laajentaa määritettyä superluokkaa ja on koristeltu vastaavalla attribuutilla.

Voit luonnollisesti lisätä rakennusmenetelmään niin paljon vahvistusta tai logiikkaa kuin haluat, mutta tärkeä poiminta tässä on, että kun se on otettu käyttöön, sinun ei koskaan tarvitse muokata tätä menetelmää uudelleen. Voit lisätä alaluokkia hierarkiaan ja niin kauan kuin varmistat, että koristelet ne asianmukaisesti, konstruktiomenetelmä löytää ne, vaikka niitä ei ollut olemassa kirjoitettaessa.

Entä suorituskyky? Rehellisesti sanottuna en ole yrittänyt vertailla sitä, mutta sisäinen tunne on, että tämä toimii luultavasti huonommin kuin klassinen kytkinlausekesuunnittelu. Ottaen kuitenkin huomioon, että ylivoimaisesti useimmat Dynamics AX:n suorituskykyongelmat johtuvat tietokannan käytöstä, en olisi siitä liikaa huolissani.

Tietysti, jos toteutat jotain, joka vaatii tuhansien objektien nopean luomisen, saatat haluta tutkia asiaa tarkemmin, mutta klassisissa tapauksissa, joissa vain instantoit yksittäistä objektia pitkää käsittelyä varten, epäilen, että sillä on merkitystä. Vianetsintävinkkini (seuraava kappale) huomioon ottaen näyttää myös siltä, ​​että SysExtension-kehys perustuu välimuistiin, joten epäilen, että sillä ei ole merkittävää suorituskykyä heikentyneessä järjestelmässä. Vianetsintä: Jos rakennusmenetelmä ei löydä alaluokkiasi, vaikka olet varma, että ne on sisustettu oikein, se voi olla välimuistiongelma. Yritä tyhjentää sekä asiakkaan että palvelimen välimuistit. AOS:n ei pitäisi olla tarpeen käynnistää uudelleen, mutta se voi olla viimeinen keino.

Jaa BlueskyssäJaa FacebookissaJaa LinkedInissäJaa TumblrissaJaa X:ssäJaa LinkedInissäPin Pinterestissä

Mikkel Bang Christensen

Kirjoittajasta

Mikkel Bang Christensen
Mikkel on miklix.com-sivuston luoja ja omistaja. Hänellä on yli 20 vuoden kokemus ammattimaisena tietokoneohjelmoijana/ohjelmistokehittäjänä, ja tällä hetkellä hän työskentelee kokopäiväisesti suuressa eurooppalaisessa IT-yrityksessä. Kun hän ei ole bloggaamassa, hän käyttää vapaa-aikaansa monenlaisiin kiinnostuksen kohteisiin, harrastuksiin ja aktiviteetteihin, mikä saattaa jossain määrin heijastua tällä verkkosivustolla käsiteltävien aiheiden moninaisuuteen.